聯通spApi.jar短信接口二次開發
提示:調試時一定要和聯通工程師聯調,讓他們監控服務端,可能存在ip授權,手機號碼白名單的問題。不要執着於代碼和配置參數的檢查。
1.新建web工程,導入聯通spApi.jar包
2.創建一個配置類SmsRequest
package com;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class SmsRequest
{
public String cLocalIp;
public int iLocalPort;
public String cSmgIp;
public int cSmgPort;
public String cLoginName;
public String cPassword;
public int lSocketTimeOut;
public int lMTTimeOut;
public long iSrcNode;
public int lMTThread;
public int lMaxListNode;
public int lMTMaxRetryTime;
public int lMOThread;
public String corpId;
public String service_type;
public byte fee_type;
public String fee_value;
public String given_value;
public byte agent_flag;
public byte mo_flag;
public byte priority;
public String expire_time;
public byte report_flag;
public byte tp_pid;
public byte tp_udhi;
public byte message_coding;
public byte messagetype;
public String chargenumber;
public String ScheduleTime;
public String spnumber;
public String content;
public int message_length;
public long messageid;
public int startUpResult;
public int submitResult;
public int submitError;
public long sequencenumber1;
public long sequencenumber2;
public long sequencenumber3;
public int sysid;
public String sysloginname;
public String syspassword;
public String posturl;
public String mmsposturl;
public SmsRequest()
{
GetsmsRequest();
}
public void GetsmsRequest()
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
System.out.print(pce.toString());
}
Document doc = null;
String className = SmsRequest.class.getName();
String classNamePath = className.replace(".", "/") + ".class";
URL xmlpath = SmsRequest.class.getClassLoader().getResource(classNamePath);
System.out.println("xmlpath="+xmlpath.toString());
String xmlfile=xmlpath.toString();
xmlfile = xmlfile.substring(0,xmlfile.lastIndexOf("/"));
xmlfile = xmlfile.substring(0,xmlfile.lastIndexOf("/"));
xmlfile = xmlfile.substring(0,xmlfile.lastIndexOf("/"));
xmlfile = xmlfile.substring(0,xmlfile.lastIndexOf("/"));
xmlfile=xmlfile+ "/config.xml";
System.out.println("xmlfile="+xmlfile);
try
{
doc = db.parse(xmlfile);
}
catch (Exception e) {
System.out.print(e.toString());
}
Element root = doc.getDocumentElement();
NodeList startup = root.getElementsByTagName("startup");
Element start = (Element)startup.item(0);
this.cLocalIp = start.getElementsByTagName("cLocalIp").item(0).getFirstChild().getNodeValue();
this.iLocalPort = Integer.parseInt(start.getElementsByTagName("iLocalPort").item(0).getFirstChild().getNodeValue());
this.cSmgIp = start.getElementsByTagName("cSmgIp").item(0).getFirstChild().getNodeValue();
this.cSmgPort = Integer.parseInt(start.getElementsByTagName("cSmgPort").item(0).getFirstChild().getNodeValue());
this.cLoginName = start.getElementsByTagName("cLoginName").item(0).getFirstChild().getNodeValue();
this.cPassword = start.getElementsByTagName("cPassword").item(0).getFirstChild().getNodeValue();
this.lSocketTimeOut = Integer.parseInt(start.getElementsByTagName("lSocketTimeOut").item(0).getFirstChild().getNodeValue());
this.lMTTimeOut = Integer.parseInt(start.getElementsByTagName("lMTTimeOut").item(0).getFirstChild().getNodeValue());
this.iSrcNode = Long.parseLong(start.getElementsByTagName("iSrcNode").item(0).getFirstChild().getNodeValue());
this.lMTThread = Integer.parseInt(start.getElementsByTagName("lMTThread").item(0).getFirstChild().getNodeValue());
this.lMaxListNode = Integer.parseInt(start.getElementsByTagName("lMaxListNode").item(0).getFirstChild().getNodeValue());
this.lMTMaxRetryTime = Integer.parseInt(start.getElementsByTagName("lMTMaxRetryTime").item(0).getFirstChild().getNodeValue());
this.lMOThread = Integer.parseInt(start.getElementsByTagName("lMOThread").item(0).getFirstChild().getNodeValue());
NodeList submit = root.getElementsByTagName("submit");
Element sub = (Element)submit.item(0);
this.corpId = sub.getElementsByTagName("corpId").item(0).getFirstChild().getNodeValue();
this.service_type = sub.getElementsByTagName("service_type").item(0).getFirstChild().getNodeValue();
this.fee_type = Byte.parseByte(sub.getElementsByTagName("fee_type").item(0).getFirstChild().getNodeValue());
this.fee_value = sub.getElementsByTagName("fee_value").item(0).getFirstChild().getNodeValue();
this.given_value = "";
this.agent_flag = Byte.parseByte(sub.getElementsByTagName("agent_flag").item(0).getFirstChild().getNodeValue());
this.mo_flag = Byte.parseByte(sub.getElementsByTagName("mo_flag").item(0).getFirstChild().getNodeValue());
this.priority = Byte.parseByte(sub.getElementsByTagName("priority").item(0).getFirstChild().getNodeValue());
this.expire_time = "";
this.report_flag = Byte.parseByte(sub.getElementsByTagName("report_flag").item(0).getFirstChild().getNodeValue());
this.tp_pid = Byte.parseByte(sub.getElementsByTagName("tp_pid").item(0).getFirstChild().getNodeValue());
this.tp_udhi = Byte.parseByte(sub.getElementsByTagName("tp_udhi").item(0).getFirstChild().getNodeValue());
this.message_coding = Byte.parseByte(sub.getElementsByTagName("message_coding").item(0).getFirstChild().getNodeValue());
this.ScheduleTime = "";
this.spnumber = sub.getElementsByTagName("spnumber").item(0).getFirstChild().getNodeValue();
this.chargenumber = sub.getElementsByTagName("chargenumber").item(0).getFirstChild().getNodeValue();
this.messagetype = 0;
System.out.println("config.xml cLocalIp="+this.cLocalIp);
}
}
3.config.xml配置文件放在web-inf下
<?xml version="1.0" standalone="yes"?>
<config>
<startup>
<cLocalIp>你服務器ip這個是需要聯通鑑權的</cLocalIp>
<iLocalPort>你服務器port</iLocalPort>
<cSmgIp>聯通服務ip</cSmgIp>
<cSmgPort>聯通服務port</cSmgPort>
<cLoginName>用戶名聯通分配</cLoginName>
<cPassword>密碼聯通分配</cPassword>
<lSocketTimeOut>5</lSocketTimeOut>
<lMTTimeOut>10</lMTTimeOut>
<iSrcNode>節點編碼聯通分配</iSrcNode>
<lMTThread>50</lMTThread>
<lMaxListNode>50</lMaxListNode>
<lMTMaxRetryTime>5</lMTMaxRetryTime>
<lMOThread>0</lMOThread>
</startup>
<submit>
<spnumber>spid聯通分配</spnumber>
<chargenumber>000000000000000000000</chargenumber>
<corpId>聯通分配</corpId>
<service_type>TEST</service_type>
<fee_type>1</fee_type>
<fee_value>0</fee_value>
<given_value />
<agent_flag>0</agent_flag>
<mo_flag>2</mo_flag>
<priority>0</priority>
<expire_time />
<report_flag>1</report_flag>
<tp_pid>0</tp_pid>
<tp_udhi>0</tp_udhi>
<message_coding>15</message_coding>
</submit>
</config>
4.創建發送短信測試類
package com;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import spApi.Bind;
import spApi.BindResp;
import spApi.Deliver;
import spApi.SGIP_Command;
import spApi.SGIP_Exception;
import spApi.Submit;
import spApi.SubmitResp;
import spApi.Unbind;
import spApi.UnbindResp;
public class Send {
public SmsRequest request;
public Send() {
request = new SmsRequest();
}
public void printError(int ret) {
String error = "";
switch (ret){
case 0:
error="無錯誤,命令正確接收";
break;
case 1:
error="非法登錄,如登錄名、口令出錯、登錄名與口令不符等。";
break;
case 2:
error="重複登錄,如在同一TCP/IP連接中連續兩次以上請求登錄。";
break;
case 3:
error="連接過多,指單個節點要求同時建立的連接數過多。";
break;
case 4:
error="登錄類型錯,指bind命令中的logintype字段出錯。";
break;
case 5:
error="參數格式錯,指命令中參數值與參數類型不符或與協議規定的範圍不符。";
break;
case 6:
error="非法手機號碼,協議中所有手機號碼字段出現非86130號碼或手機號碼前未加“86”時都應報錯。";
break;
case 7:
error="消息ID錯";
break;
case 8:
error="信息長度錯";
break;
case 9:
error="非法序列號,包括序列號重複、序列號格式錯誤等";
break;
case 10:
error="非法操作GNS";
break;
case 11:
error="節點忙,指本節點存儲隊列滿或其他原因,暫時不能提供服務的情況";
break;
case 12:
error="關機或停機";
break;
case 21:
error="目的地址不可達,指路由表存在路由且消息路由正確但被路由的節點暫時不能提供服務的情況";
break;
case 22:
error="路由錯,指路由表存在路由但消息路由出錯的情況,如轉錯SMG等";
break;
case 23:
error="路由不存在,指消息路由的節點在路由表中不存在";
break;
case 24:
error="計費號碼無效,鑑權不成功時反饋的錯誤信息";
break;
case 25:
error="用戶不能通信(如不在服務區、未開機等情況)";
break;
case 26:
error="手機內存不足";
break;
case 27:
error="手機不支持短消息";
break;
case 28:
error="手機接收短消息出現錯誤";
break;
case 29:
error="不知道的用戶";
break;
case 30:
error="不提供此功能";
break;
case 31:
error="非法設備";
break;
case 32:
error="系統失敗";
break;
case 33:
error="短信中心隊列滿";
break;
case 51:
error="屏蔽";
break;
case 72:
error="沒有路由";
break;
default:
error="其它錯誤碼(待定義)";
}
System.out.println("【錯誤信息】:" + error);
}
@SuppressWarnings("unused")
public void sendMsg() {
Socket so = null;
OutputStream out = null;
InputStream input = null;
Bind command = null;
Bind com = null;
SGIP_Command sgip = null;
SGIP_Command tmp = null;
int i = 0;
try {
//bind連接服務
sgip = new SGIP_Command();
command = new Bind(request.iSrcNode, 1, request.cLoginName,request.cPassword);
int err;
byte[] byte_content = new byte[140];
Deliver deliver = null;
Submit submit = null;
SubmitResp submitresp = null;
Bind active = null;
Unbind term = null;
BindResp resp = null;
UnbindResp Unresp = null;
so = new Socket(request.cSmgIp, request.cSmgPort);//建立連接套接字
out = new DataOutputStream(so.getOutputStream());
input = new DataInputStream(so.getInputStream());
//發送bind數據
err = command.write(out);
if (err != 0) {
System.out.println("err" + err);
}
//接收bind返回數據
tmp = sgip.read(input);//接收sgip消息
if (sgip.getCommandID() == SGIP_Command.ID_SGIP_BIND_RESP) {
resp = (BindResp) tmp;// 強制轉換爲bindresp
resp.readbody();// 對消息進行解包
System.out.println("tmp.getSeqno_1=" + tmp.getSeqno_1());
System.out.println("tmp.getSeqno_2=" + tmp.getSeqno_2());
System.out.println("tmp.getSeqno_3=" + tmp.getSeqno_3());
System.out.println("resp.GetResult=" + resp.GetResult());
if(resp.GetResult()!=0){
printError(resp.GetResult());//0成功 其他失敗
}
}
for (i = 0; i < 140; i++) {
byte_content[i] = 51;
i++;
byte_content[i] = 51;
i++;
byte_content[i] = 52;
i++;
byte_content[i] = 53;
i++;
byte_content[i] = 54;
i++;
byte_content[i] = 55;
i++;
byte_content[i] = 56;
i++;
byte_content[i] = 57;
i++;
byte_content[i] = 58;
i++;
byte_content[i] = 59;
}
// 封裝submit數據
String mobile="";
submit = new Submit(request.iSrcNode,
request.spnumber,
request.chargenumber,
1,
"86"+mobile,
request.corpId,
request.service_type,
request.fee_type,
request.fee_value,
request.given_value,
request.agent_flag,
request.mo_flag,
request.priority,
"",
"",
request.report_flag,
request.tp_pid,
request.tp_udhi,
request.message_coding,
request.messagetype,
4,
"短信測試");
submit.write(out);//發送submit
//讀取submit返回結果
tmp = sgip.read(input);
if (tmp.getCommandID() == SGIP_Command.ID_SGIP_SUBMIT_RESP) {
submitresp = (SubmitResp) tmp;// 強制轉換
submitresp.readbody();// 解包
System.out.println("tmp.getSeqno_1=" + tmp.getSeqno_1());
System.out.println("tmp.getSeqno_2=" + tmp.getSeqno_2());
System.out.println("tmp.getSeqno_3=" + tmp.getSeqno_3());
System.out.println("submitresp.getResult="+ submitresp.getResult());
if(submitresp.getResult()!=0){
printError(submitresp.getResult());
}
}
//發送unbind
term = new Unbind(request.iSrcNode);
term.write(out);
tmp = sgip.read(input);
if (sgip.getCommandID() == SGIP_Command.ID_SGIP_UNBIND_RESP) {
Unresp = (UnbindResp) tmp;
System.out.println("tmp.getSeqno_1=" + tmp.getSeqno_1());
System.out.println("tmp.getSeqno_2=" + tmp.getSeqno_2());
System.out.println("tmp.getSeqno_3=" + tmp.getSeqno_3());
}
//關閉流和套接字
out.close();
so.close();
} catch (SGIP_Exception e) {
System.out.println(e.toString());
} catch (Exception e) {
System.out.println(e.toString());
} finally {
try {
System.in.read();
} catch (Exception s) {
System.out.println(s.toString());
}
}
}
}
5.測試調用
Send send=new Send();
send.sendMsg();