对接 亿美短信平台 总结(HttpClient的使用)

来源:互联网 发布:openwrt 修改无线mac 编辑:程序博客网 时间:2024/04/30 10:17

最近做项目,需要使用“亿美”的短信服务,其实没多少内容,主要就是发送http请求,完成后,在此总结一番。

1、亿美软通SDK开发说明

     亿美短信SDK:是针对独立软件开发商(ISV)和系统集成商(SI)的软件开发及技术产品服务的需求,提供的短信通讯开发组件(SDK,Software Development Kit)。

2、定义

     MT  Message Terminal——下行短信,即向手机终端发送短信
     MO  Message Original——上行短信,即手机用户向特服号码发送短信企业特服号码 由亿美为SDK用户分配的属于该用户专用的特服号码。

    项目主要使用MT,即平台向手机终端发送短信。

3、开发流程

合作伙伴必须通过亿美软通或是亿美软通代理商,取得SDK开发包和相关文档,

取得供由本SDK使用的序列号及密码,这些参数将用于服务注册及短信发送。

接口调用流程如下:


永久执行

Ø  序列号首次使用时执行一次,就像我们的信用卡一样,首次使用必须激活一次(我的项目只需要执行这个即可使用亿美的发送短信功能,当然也需要亿美方进行一些注册的操作)

Ø  调用软件序列号注销以后,再次使用该序列号时必须重新激活

运行时执行

Ø  主要是发送短信接口,软件序列号激活以后便可以随时使用我们的短信发送接口,前提是软件序列号处于激活状态

需要时执行

Ø  需要时执行的方法,调用频率相对较低,我们可以在需要的时候调用一次啊,前提是软件序列号处于激活状态

结束执行

Ø 此接口一旦调用该软件序列号便不能在使用,即不能发送短信等,直到下次重新激活

4、具体的步骤

第一步:进行序列号的注册:http://bj999.eucp.b2m.cn:8080/sdkproxy/regist.action

第二步:发送即时短信的服务:http://bj999.eucp.b2m.cn:8080/sdkproxy/sendsms.action

主要就这两步,其实很简单,根据亿美给的test用例,很快即可使用。

5、代码详解

注册序列号的我们就不关心了,我们看调用发短信的方法:

smsService.sendSMS("13918886474", "【陆金所】"+"这是要发的短信内容");

短信内容前面一定要加:【xxx】

里面的xxx与亿美协定好,亿美称之为“签名”,不加的话,短信无法最终发送成功,获取报告可知:EM104  无签名失败 (移动号码)

sendSMS的具体实现:

 /** 发送即时短信:下发get     *      * @param url     * @param param     * @return 0:代表成功, 其他:参考亿美文档     */    @Override    public  String sendSMS(String mobile, String message) {                try {            message = URLEncoder.encode(message, "UTF-8");        } catch (UnsupportedEncodingException ex) {            logger.warn("exception happened while encode the message:{}!",ex);        }        String code = "";        long seqId = System.currentTimeMillis();        String param = "cdkey=" + appBean.getSmsConfig().getSn() + "&password=" + appBean.getSmsConfig().getPassword()+ "&phone=" + mobile + "&message=" + message + "&addserial=" + code + "&seqid=" + seqId;        String url = appBean.getSmsConfig().getBaseEmayUrl()+ "sendsms.action";        String ret = "";        url = url + "?" + param;        logger.info("【SDKHttpClient】短信发送请求到SDK:url={}", url);        String responseString = HttpClientUtil.getInstance().doGetRequest(url);        responseString = responseString.trim();        if (null != responseString && !"".equals(responseString)) {            ret = xmlMt(responseString);        }        return ret;    }
需要注意的几点:

  1. 发送的message即短信内容,需要进行URLEncoder.encode(message, "UTF-8")此操作,我们不能直接将中文发送出去,需要进行转码。

  2. 主要就是拼装一个url,如下这种格式,多个手机号用英文逗号隔开。

http://bj999.eucp.b2m.cn:8080/sdkproxy/sendsms.action?cdkey=2SDK-EMY-6688-AAAAA&password=123&phone=1333333333&message=短信测试&addserial=10086


关于具体的发送httpclient的请求:HttpClientUtil.getInstance().doGetRequest(url),如下代码:

package cn.emay.channel.httpclient;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpException;import org.apache.commons.httpclient.HttpMethod;import org.apache.commons.httpclient.HttpStatus;import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.methods.PostMethod;import org.apache.commons.httpclient.params.HttpConnectionManagerParams;import org.slf4j.LoggerFactory;public class HttpClientUtil {        private final static org.slf4j.Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);    private static HttpClient client = null;    // 构造单例    private HttpClientUtil() {        MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();        HttpConnectionManagerParams params = new HttpConnectionManagerParams();        // 默认连接超时时间        params.setConnectionTimeout(60000);        // 默认读取超时时间        params.setSoTimeout(60000);        // 默认单个host最大连接数        params.setDefaultMaxConnectionsPerHost(200);// very important!!        // 最大总连接数        params.setMaxTotalConnections(500);// very important!!        httpConnectionManager.setParams(params);        client = new HttpClient(httpConnectionManager);        client.getParams().setConnectionManagerTimeout(3000);        // client.getParams().setIntParameter("http.socket.timeout", 10000);        // client.getParams().setIntParameter("http.connection.timeout", 5000);    }    private static class ClientUtilInstance {        private static final HttpClientUtil ClientUtil = new HttpClientUtil();    }    public static HttpClientUtil getInstance() {        return ClientUtilInstance.ClientUtil;    }    /**     * 发送http GET请求,并返回http响应字符串     *      * @param urlstr  完整的请求url字符串     * @return     */    public String doGetRequest(String urlstr) {                String response = "";        HttpMethod httpmethod = new GetMethod(urlstr);        try {            int statusCode = client.executeMethod(httpmethod);            InputStream _InputStream = null;            if (statusCode == HttpStatus.SC_OK) {                _InputStream = httpmethod.getResponseBodyAsStream();            }            if (_InputStream != null) {                response = GetResponseString(_InputStream, "UTF-8");            }        } catch (HttpException e) {            logger.error("获取响应错误,原因:" + e.getMessage());        } catch (IOException e) {            logger.error("获取响应错误,原因1:" + e.getMessage());        } finally {            httpmethod.releaseConnection();        }        return response;    }    public String doPostRequest(String postUrl) {        String response = "";        PostMethod postMethod = new PostMethod(postUrl);        try {        //postMethod.getParams().setContentCharset("utf-8");            int statusCode = client.executeMethod(postMethod);            if (statusCode == HttpStatus.SC_OK) {                InputStream _InputStream = null;                if (statusCode == HttpStatus.SC_OK) {                    _InputStream = postMethod.getResponseBodyAsStream();                }                if (_InputStream != null) {                    response = GetResponseString(_InputStream, "UTF-8");                }            }        } catch (HttpException e) {            logger.error("获取响应错误,原因:" + e.getMessage());        } catch (IOException e) {            logger.error("获取响应错误,原因1:" + e.getMessage());        } finally {            postMethod.releaseConnection();        }        return response;    }    /**     *      * @param _InputStream     * @param Charset     * @return     */    public String GetResponseString(InputStream _InputStream, String Charset) {        String response = "";        try {            if (_InputStream != null) {                StringBuffer buffer = new StringBuffer();                InputStreamReader isr = new InputStreamReader(_InputStream, Charset);                Reader in = new BufferedReader(isr);                int ch;                while ((ch = in.read()) > -1) {                    buffer.append((char) ch);                }                response = buffer.toString();                buffer = null;            }        } catch (IOException e) {            logger.error("获取响应错误,原因:" + e.getMessage());            response = response + e.getMessage();        }        return response;    }}

主要看以下这几行代码:

HttpMethod httpmethod = new GetMethod(urlstr);try {    int statusCode = client.executeMethod(httpmethod);    InputStream _InputStream = null;    if (statusCode == HttpStatus.SC_OK) {        _InputStream = httpmethod.getResponseBodyAsStream();    }    if (_InputStream != null) {        response = GetResponseString(_InputStream, "UTF-8");    }} catch (HttpException e) {    logger.error("获取响应错误,原因:" + e.getMessage());} catch (IOException e) {    logger.error("获取响应错误,原因1:" + e.getMessage());} finally {    httpmethod.releaseConnection();}

用的是get的请求,如果需要用post的请求,将

HttpMethod httpmethod = new GetMethod(urlstr);

改写成:

HttpMethod postMethod = new PostMethod(postUrl);

至于返回的内容进行解析,根据亿美提供的样子进行处理即可。

此处只是保证短信被亿美接受了,但真正接受人有没有收到,需要发送另外一个接口查询:

http://bj999.eucp.b2m.cn:8080/sdkproxy/getreport.action,本文具体的url需要以亿美提供的为主,此处只作展示

此接口返回的数据如下:主要看状态和手机号码,根据这些记录,你可以选择性的重发短信。


它会提供给你短信发送是否成功:有以下状态


除了0和DELIVRD,其他默认都是失败。
第一类:
EM101  黑字典 失败
EM106  签名未报备失败
EM104  无签名失败 (移动号码)
EM105  无签名失败 (联通或电信)  
EM001  十分钟内频繁下发过滤失败
EM2000  无签名失败 
EM2001  双签名失败 
NOTITLE   NOUNSUB  短信未加退订
UNDELIV  用户因为状态不正确如处于停机、挂起等状态而导致用户无法接收到短信  也有可能是运营商黑名单
IB:0008  是网关瞬间提交量过大速度过快导致的
REJECTD  内容有问题   发送不了被拒绝
E:ODML  单个号码超出每天接收短信的条数限制了(特殊限制通道)  

第二类:关机、停机
MK0012:  空号
MK0015:停机  关机
MK0005: 停机关机
MK0010:停机关机
MK0001:停机关机
MI:0029 关机、停机
MK:0000   停机

第三类:黑名单
EM101
含有BLACK字样
86
12
67
24
110
DB:0141
DB:0144
DB0164
Tuiding
MOBFAIL
由于状态值非常多而且是不断更新的,所以其他状态值可以默认为手机端号码问题,例如空号停机关机无服务等问题

关于httpclient的使用说明,可以看http://www.cnblogs.com/ITtangtang/p/3968093.html这篇文章的说明。

1 0