1

我有一个 java 代码可以向 SMPP 提交长短信,但是在执行时我得到“长度必须小于或等于 254。实际长度为 270 ”错误。使用长字符串或任何阿拉伯字符时。

谁能帮我找出原因并建议我如何解决问题。

下面是我正在尝试的代码。

import java.io.IOException;
import java.util.Date;
import java.util.Random;

import org.jsmpp.InvalidResponseException;
import org.jsmpp.PDUException;
import org.jsmpp.bean.Alphabet;
import org.jsmpp.bean.BindType;
import org.jsmpp.bean.ESMClass;
import org.jsmpp.bean.GeneralDataCoding;
import org.jsmpp.bean.MessageClass;
import org.jsmpp.bean.NumberingPlanIndicator;
import org.jsmpp.bean.OptionalParameter;
import org.jsmpp.bean.OptionalParameters;
import org.jsmpp.bean.RegisteredDelivery;
import org.jsmpp.bean.SMSCDeliveryReceipt;
import org.jsmpp.bean.TypeOfNumber;
import org.jsmpp.extra.NegativeResponseException;
import org.jsmpp.extra.ResponseTimeoutException;
import org.jsmpp.session.BindParameter;
import org.jsmpp.session.SMPPSession;
import org.jsmpp.util.AbsoluteTimeFormatter;
import org.jsmpp.util.TimeFormatter;

public class SendLongSMSMessage
{
        private static TimeFormatter    timeFormatter   = new AbsoluteTimeFormatter();

    public String[] submitLongSMS(String MSISDN, String senderAddr, String message) throws Exception
    {
            SMPPSession session = getSession();

            String[] msgId = null;
            int splitSize = 135;
            int totalSize = 140;
            int totalSegments = 0;

            RegisteredDelivery registeredDelivery = new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT);

            GeneralDataCoding dataCoding = new GeneralDataCoding(false, false, MessageClass.CLASS1,
            Alphabet.ALPHA_8_BIT);
            ESMClass esmClass = new ESMClass();

            if (message != null && message.length() > totalSize)
            {
                    totalSegments = getTotalSegmentsForTextMessage(message);
            }

            Random random = new Random();
            OptionalParameter sarMsgRefNum = OptionalParameters.newSarMsgRefNum((short) random.nextInt());
            OptionalParameter sarTotalSegments = OptionalParameters.newSarTotalSegments(totalSegments);

            String[] segmentData = splitIntoStringArray(message, splitSize, totalSegments);

            msgId = new String[totalSegments];
            for (int i = 0, seqNum = 0; i < totalSegments; i++)
            {
                    seqNum = i + 1;
                    OptionalParameter sarSegmentSeqnum = OptionalParameters.newSarSegmentSeqnum(seqNum);
                    try
                    {       byte[] byteText = segmentData[i].getBytes("UTF-16BE");
                            msgId[i] = session.submitShortMessage("", TypeOfNumber.NATIONAL,
                            NumberingPlanIndicator.ISDN, "9999999999", TypeOfNumber.NATIONAL,
                            NumberingPlanIndicator.ISDN, MSISDN, esmClass, (byte) 0, (byte) 0, timeFormatter
                            .format(new Date()), null, registeredDelivery, (byte) 0, dataCoding, (byte) 0, byteText, sarMsgRefNum, sarSegmentSeqnum, sarTotalSegments);

                            System.out.println("Message id  for segment " + seqNum + " out of totalsegment "
                            + totalSegments + "is" + msgId[i]);

                    }
                    catch (PDUException e)
                    {
                            System.out.println("PDUException has occured" + e.getMessage());
                    }
                    catch (ResponseTimeoutException e)
                    {
                            System.out.println("ResponseTimeoutException has occured" + e.getMessage());
                    }
                    catch (InvalidResponseException e)
                    {
                            System.out.println("InvalidResponseException has occured" + e.getMessage());
                    }
                    catch (NegativeResponseException e)
                    {
                            System.out.println("NegativeResponseException has occured" + e.getMessage());
                    }
                    catch (IOException e)
                    {
                            System.out.println("IOException has occured" + e.getMessage());
                    }
            }
             session.unbindAndClose();
            return msgId;
    }

    private SMPPSession getSession() throws Exception
    {
            return newSession();
    }

    private SMPPSession newSession() throws Exception
    {
            BindParameter bindParam = new BindParameter(BindType.BIND_TX, "<user_name>", "<pass_word>", "tdd",
            TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null);

            return new SMPPSession("17.1.1.1", 6666, bindParam);
    }

    public int getTotalSegmentsForTextMessage(String message)
    {
            int splitPos = 135;
            int totalsegments = 1;
            if (message.length() > splitPos)
            {
                    totalsegments = (message.length() / splitPos) + ((message.length() % splitPos > 0) ? 1 : 0);
            }
            return totalsegments;
    }

    public String[] splitIntoStringArray(String msg, int pos, int totalSegments)
    {
            String[] segmentData = new String[totalSegments];
            if (totalSegments > 1)
            {
                    int splitPos = pos;

                    int startIndex = 0;

                    segmentData[startIndex] = new String();
                    segmentData[startIndex] = msg.substring(startIndex, splitPos);

                    for (int i = 1; i < totalSegments; i++)
                    {
                            segmentData[i] = new String();
                            startIndex = splitPos;
                            if (msg.length() - startIndex <= pos)
                            {
                                    segmentData[i] = msg.substring(startIndex, msg.length());
                            }
                            else
                            {
                                    splitPos = startIndex + pos;
                                    segmentData[i] = msg.substring(startIndex, splitPos);
                            }
                    }
            }
            return segmentData;
    }

    public static void main(String[] args) throws Exception
    {
            SendLongSMSMessage slSMS = new SendLongSMSMessage();

            String message = "Tech Dive heralds the arrival of a community of Developers "
            + "who share, collaborate and exchange ideas, concepts, technical know-how. "
            + "This forum lets you take a deep dive in technical topics that are hot and happening as well as on legacy systems."
            + "The idea of the forum is to ensure collaboration amongst developers through exchange of ideas/concepts "
            + "so their technical skills are enhanced."
            + "We plan to bring in experienced professionals on board so content/blog written is authentic and precise."
            + "Come, join us and be a part of new way of collaboration!";

            String MSISDN = "9500000000";

            String senderAddr = "8500000000";

            slSMS.submitLongSMS(MSISDN, senderAddr, message);
    }
}
4

1 回答 1

0

解决此类问题的最佳来源是使用 SMPP 官方文档: https ://smpp.org/SMPP_v3_4_Issue1_2.pdf

要发送带有长消息的 SubmitSm,您需要使用名为 message_payload 的 optional_parameter 而不是常见的 short_message 参数。

您也可以在文档中阅读此信息:

可以在 sm_length 字段中指定的最大消息长度为 254 个八位字节。如果 ESME 希望提交长度大于 254 字节的消息,则 sm_length 字段必须设置为 NULL,并且 message_payload 可选参数必须填充消息长度值和用户数据。

要解决您的问题,您需要在每次发送消息时检查其中有多少字节,如果超过 254,请添加 message_payload 作为您的 optional_parameter 而不是 short_message。

使用 cloudhopper 库,您可以这样做:

    if (length > 254) {
        submitSm.setOptionalParameter(new Tlv(
                SmppConstants.TAG_MESSAGE_PAYLOAD,
                CharsetUtil.encode(messageBody, CharsetUtil.CHARSET_UCS_2),
                "message_payload"));
    } else {
        submitSm.setShortMessage(CharsetUtil.encode(messageBody, CharsetUtil.CHARSET_UCS_2));
    }
于 2020-04-08T00:03:39.800 回答