当前位置: 首页 > 工具软件 > SMProxy > 使用案例 >

使用移动代理CMPP2.0,3.0协议实现短信发送-Java版,使用华为smproxy.jar包

伍心水
2023-12-01

本文使用的是CMPP2.0,CMPP3.0和此逻辑类似,使用的Java类不同而已

1.配置文件 cmpp.xml

 

<config>
	<!--与InfoX建立连接所需参数-->
    <ismg>
       <!-- InfoX主机地址,与移动签合同时移动所提供的地址 需修改-->
       <host>127.0.0.1</host>
       <!-- InfoX主机端口号 cmpp2.0默认为7890,cmpp3.0为7891-->
       <port>7890</port>
       <!--(登录帐号SP…ID)与移动签合同时所提供的企业代码 6位  需修改-->
       <source-addr>123456</source-addr>
       <!--登录密码 默认为空 如有需修改-->
       <shared-secret>123456</shared-secret>
       <!-- 心跳信息发送间隔时间(单位:秒) -->
       <heartbeat-interval>10</heartbeat-interval>
       <!-- 连接中断时重连间隔时间(单位:秒)-->
       <reconnect-interval>10</reconnect-interval>
       <!-- 需要重连时,连续发出心跳而没有接收到响应的个数(单位:个)-->
       <heartbeat-noresponseout>5</heartbeat-noresponseout>
       <!-- 操作超时时间(单位:秒) -->
       <transaction-timeout>10</transaction-timeout>
       <!--双方协商的版本号(大于0,小于256)-->
       <version>1</version>
       <!--是否属于调试状态,true表示属于调试状态,所有的消息被打印输出到屏幕,false表示不属于调试状态,所有的消息不被输出-->
       <debug>true</debug>
    </ismg>
</config>

2.创建SMProxy 对象,建立连接,这里最好使用单例模式创建

private static String path=Thread.currentThread().getContextClassLoader().getResource("cmpp.xml").getPath().toString();
Args args1 = new Cfg(path).getArgs("ismg");
SMProxy smProxy = new SMProxy(args1); //CMPP3.0的话就是  SMProxy30 smProxy = new SMProxy30(args1);
//path为xml文件的路径;

遇到的问题:

(1)如果报xml文件读取之类的错误,请检查XML文件的格式,查看smproxy.jar中的com/huawei/insa2/comm/cmpp/resource_zh.xml文件,修改此文件的编码格式为UTF-8(用记事本打开,另存为时选择编码);
不行的话可以用我修改过的https://download.csdn.net/download/leiliz/10878273

(2)在此之前,我们向移动对接人员提供过一个IP地址,发送短信的出口必须经过此IP地址;

3.短短信发送(短信字节(byte)少于等于140)

创建消息体:2.0举例: 

 

String[] dest_Terminal_Id = {"13200000000"};
byte[] msg_Content = "您的验证码是123456".getBytes("GB2312");
CMPPSubmitMessage submitMsg = new CMPPSubmitMessage(
	1,//@pk_Total 相同msg_Id消息总条数,短短信这里是1
	1,//@pk_Number 相同msg_Id的消息序号
	1,//@registered_Delivery 是否要求返回状态报告
	1,//@msg_Level  信息级别
	"",// @service_Id 业务类型 用户自定义 用来分类查询
	2,//@fee_UserType 0对目的终端计费;1对源终端计费;2对SP计费;
	"",//@fee_Terminal_Id 被计费用户的号码
	0,//@tp_Pid GSM协议类型 一般文本的时候设0,铃声图片设1
	0,//@tp_Udhi GSM协议类型 0不包含头部信息 1包含头部信息
	15,//@msg_Fmt 消息格式 
	"123456",//@msg_Src 消息内容来源 6位的企业代码,这里需修改
	"02",// @fee_Type 资费类别 一般为02:按条计信息费
	"0",//@fee_Code 资费代码(以分为单位)
	null,//@valid_Time 存活有效期
	null,//@at_Time 定时发送时间
	"1065760000000",//@src_Terminal_Id 移动所提供的服务代码  此处需修改
	dest_Terminal_Id,//@dest_Terminal_Id 接收业务的MSISDN号码,就是接收短信的手机号,String数组
	msg_Content,//@msg_Content 消息内容 byte[],发送的消息内容,需要转化为byte[]
	"" //预留
);
CMPPSubmitRepMessage sub = (CMPPSubmitRepMessage)smProxy.send(submitMsg);//这里的smProxy就是第2点中用单例创建的smProxy对象
if(sub.getResult() == 0){
	//发送成功
}

 

4.长短信发送(内容大于140字节)

首先要将内容按140长度分割,得到一个数组或List,也是byte[],例如List<byte[]>

附上分割短信的全部代码,一个类:

public class LongMessageByte {
	public static List<byte[]> getLongByte(String message){
		List<byte[]> list = new ArrayList<byte[]>();
		try {
			byte[] messageUCS2 = message.getBytes("UnicodeBigUnmarked");//转换为byte[]
			int messageUCS2Len = messageUCS2.length;// 长短信长度
			int maxMessageLen = 140;
			if (messageUCS2Len > maxMessageLen) {// 长短信发送
				//int tpUdhi = 1; 
				//长消息是1.短消息是0
				//int msgFmt = 0x08;//长消息不能用GBK
				int messageUCS2Count = messageUCS2Len / (maxMessageLen - 6) + 1;// 长短信分为多少条发送
				byte[] tp_udhiHead = new byte[6];
				Random random = new Random();
				random.nextBytes(tp_udhiHead);//随机填充tp_udhiHead[3] 标识这批短信
				tp_udhiHead[0] = 0x05;
				tp_udhiHead[1] = 0x00;
				tp_udhiHead[2] = 0x03;
//				tp_udhiHead[3] = 0x0A;
				tp_udhiHead[4] = (byte) messageUCS2Count;
				tp_udhiHead[5] = 0x01;// 默认为第一条
				for (int i = 0; i < messageUCS2Count; i++) {
					tp_udhiHead[5] = (byte) (i + 1);
					byte[] msgContent;
					if (i != messageUCS2Count - 1) {// 不为最后一条
						msgContent=byteAdd(tp_udhiHead,messageUCS2, i*(maxMessageLen-6),(i+1)*(maxMessageLen-6));
						list.add(msgContent);
					} else {
						msgContent=byteAdd(tp_udhiHead,messageUCS2, i*(maxMessageLen-6), messageUCS2Len);
						list.add(msgContent);
					}
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	private static byte[] byteAdd(byte[] tpUdhiHead, byte[] messageUCS2, int i,int j) {
		byte[] msgb = new byte[j-i+6];
		System.arraycopy(tpUdhiHead,0,msgb,0,6);
		System.arraycopy(messageUCS2,i,msgb,6,j-i);
		return msgb;
	}
}

 

举例:

 

String[] dest_Terminal_Id={"13200000000"};
List<byte[]> list = LongMessageByte.getLongByte("您好!哈哈哈哈哈哈哈哈哈哈哈哈......");//截取短信内容并配置参数,这个内容要大于70汉字
for (int i = 0; i < list.size(); i++) {
	CMPPSubmitMessage submitMsg = new CMPPSubmitMessage(
		list.size(),//@pk_Total 相同msg_Id消息总条数 
		i+1,//@pk_Number 相同msg_Id的消息序号
		1,//@registered_Delivery 是否要求返回状态报告
		1,//@msg_Level  信息级别
		"",// @service_Id 业务类型 用户自定义 用来分类查询
		2,//@fee_UserType 0对目的终端计费;1对源终端计费;2对SP计费;
		"",//@fee_Terminal_Id 被计费用户的号码
		0,//@tp_Pid GSM协议类型 一般文本的时候设0,铃声图片设1
		1,//@tp_Udhi  0不包含头部信息 1包含头部信息 必须为1
		8,//@msg_Fmt 消息格式 设为UCS2编码
		"123456",//@msg_Src 消息内容来源 6位的企业代码
		"02",// @fee_Type 资费类别 一般为02:按条计信息费
		"0",//@fee_Code 资费代码(以分为单位)
		null,//@valid_Time 存活有效期
		null,//@at_Time 定时发送时间
		"106576000000",//@src_Terminal_Id 移动所提供的服务代码 此处需修改
		dest_Terminal_Id,//@dest_Terminal_Id 接收业务的MSISDN号码
		list.get(i),//@msg_Content 消息内容 byte[]
		"" //预留   3.0这里是String LinkID,点播业务使用的LinkID,非点播类业务的MT流程不使用该字段。
	);
	CMPPSubmitRepMessage sub = (CMPPSubmitRepMessage)smProxy.send(submitMsg);//这里的smProxy就是第2点中用单例创建的smProxy对象
	if(sub.getResult() == 0){
		//本条发送成功
	}
}

移动会把多条短信(长短信分割)合成一条发送到手机

如果要使用3.0 更换以下类

SMProxy -->SMProxy30

CMPPSubmitMessage -->CMPP30SubmitMessage

CMPPSubmitRepMessage -->CMPP30SubmitRepMessage

如有问题请联系

 类似资料: