短信通知接口json报文开发设计总结

​​​短信渠道接口详细设计总计

    这两天就一直写设计文档,毕竟第一次开发短信的接口,一开始还是比较懵逼的,主要是不明白总体通讯的流程,所以设计起来比较花时间。

    经过老大的提示了,也是明白了大概的接口通讯流程:前台接口通过调用接口发起短信通知接口,将信息组织为json 格式报文发往后台,后台处理报文数据,发往某短信提供方,厂商接收后实时返回短信发送状态。这是是厂商将短信内容发往相应的客户的手机,异步通知给我们平台,报告这次短信的发送最终状态。(划重点)

    大致的通讯流程同支付接口一样。将我们需要给客户处理的信息发送给第三方厂商处理,厂商处理完成,异步通知我们处理结果,然后我们相应的处理最终的数据。嗯,一样的流程。之前公司调我一个人去民生银行去开发一致润联支付接口,终于把支付接口搞明白了。

    话说回来短信接口的设计,需要根据平台系统本身出发,厂商提供三个接口:短信下发接口(没有参数,静态的短信文字内容)、变量短信接口(HTTPS请求方式,同时支持不同变量的短信内容)、回送状态报告接口(即异步通知接口)。

    根据平台需要发送的短信内容,只需要选择变量短信接口和异步通知接口。

    接口文档就不需要看了,其中有两个字段需要注意msg短信内容、params手机号码和变量参数。

"msg":" 欢迎您注册象聚金元,您的注册验证码为:{$val},如非本人操作,可忽略本短信。成功注册后您将获得{$val}元新手体验金! ";

"params":"155****6033,123456,1288;185****8669,654321,1288";

其中的两个字段参数内容如上所示,多个用户对象以";"分号隔开,内部的参数以","逗号隔开。

第一个是手机号,","逗号后的分别是{$val}的参数值。例如: 欢迎您注册象聚金元,您的注册验证码为:123456,如非本人操作,可忽略本短信。成功注册后您将获得1288元新手体验金!

嗯,厂商给我们文档的时候,没有说明params的内容是什么意思,还是自己测试出来明白的。蛋疼(印象减分),所以文档写好,还是有必要的(我写得很挫,文字太过口语化)。

变量短信接口请求报文变量短信接口请求报文

​平台需要,需要记录每一条发送的短信记录,提供和客户查阅(防止扯皮),由于客户提的需求中,有很多不同场景的不同模板短信内容:购买理财时发送短信给用户提示购买成功等一些信息,到了产品到期或者兑付日也发送短信提示用户相关信息。这些属于群发短信通知。

    只需要开发一个公共的通讯接口提供上述不同场景调用即可。同时需要新建一个服务端的DTA,作为异步通知DTA供厂商调用,发送异步通知接口到平台,根据唯一标识符sms_id来更新表字段状态,成功或者失败,完成整个流程。

    写了个类,仅仅用户接口测试。

//java代码测试短信接口连通性demo,仅测试用,敏感信息已屏蔽

public class HttpUtil(){

    private static PoolingHttpClientConnectionManager connMgr;  

    private static RequestConfig requestConfig;  

    private static final int MAX_TIMEOUT = 7000;  

    static {  

        // 设置连接池  

        connMgr = new PoolingHttpClientConnectionManager();  

        // 设置连接池大小  

        connMgr.setMaxTotal(100);  

        connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());  

        RequestConfig.Builder configBuilder = RequestConfig.custom();  

        // 设置连接超时  

        configBuilder.setConnectTimeout(MAX_TIMEOUT);  

        // 设置读取超时  

        configBuilder.setSocketTimeout(MAX_TIMEOUT);  

        // 设置从连接池获取连接实例的超时  

        configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);  

        // 在提交请求之前 测试连接是否可用  

        configBuilder.setStaleConnectionCheckEnabled(true);  

        requestConfig = configBuilder.build();  

    }  

    /** 

     * 发送 GET 请求(HTTP),不带输入数据 

     * @param url 

     * @return 

     */  

    public static String doGet(String url) {  

        return doGet(url, new HashMap<String, Object>());  

    }  

    /** 

     * 发送 GET 请求(HTTP),K-V形式 

     * @param url 

     * @param params 

     * @return 

     */  

    public static String doGet(String url, Map<String, Object> params) {  

        String apiUrl = url;  

        StringBuffer param = new StringBuffer();  

        int i = 0;  

        for (String key : params.keySet()) {  

            if (i == 0)  

                param.append("?");  

            else  

                param.append("&");  

            param.append(key).append("=").append(params.get(key));  

            i++;  

        }  

        apiUrl += param;  

        String result = null;  

        HttpClient httpclient = new DefaultHttpClient();  

        try {  

            HttpGet httpPost = new HttpGet(apiUrl);  

            HttpResponse response = httpclient.execute(httpPost);  

            int statusCode = response.getStatusLine().getStatusCode();  

            System.out.println("执行状态码 : " + statusCode);  

            HttpEntity entity = response.getEntity();  

            if (entity != null) {  

                InputStream instream = entity.getContent();  

                result = IOUtils.toString(instream, "UTF-8");  

            }  

        } catch (IOException e) {  

            e.printStackTrace();  

        }  

        return result;  

    }  

    /** 

     * 发送 POST 请求(HTTP),不带输入数据 

     * @param apiUrl 

     * @return 

     */  

    public static String doPost(String apiUrl) {  

        return doPost(apiUrl, new HashMap<String, Object>());  

    }  

    /** 

     * 发送 POST 请求(HTTP),K-V形式 

     * @param apiUrl API接口URL 

     * @param params 参数map 

     * @return 

     */  

    public static String doPost(String apiUrl, Map<String, Object> params) {  

        CloseableHttpClient httpClient = HttpClients.createDefault();  

        String httpStr = null;  

        HttpPost httpPost = new HttpPost(apiUrl);  

        CloseableHttpResponse response = null;  

        try {  

            httpPost.setConfig(requestConfig);  

List<NameValuePair> pairList = new ArrayList<>(params.size());

            for (Map.Entry<String, Object> entry : params.entrySet()) {  

                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry  

                        .getValue().toString());  

                pairList.add(pair);  

            }  

            httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));  

            response = httpClient.execute(httpPost);  

            System.out.println(response.toString());  

            HttpEntity entity = response.getEntity();  

            httpStr = EntityUtils.toString(entity, "UTF-8");  

        } catch (IOException e) {  

            e.printStackTrace();  

        } finally {  

            if (response != null) {  

                try {  

                    EntityUtils.consume(response.getEntity());  

                } catch (IOException e) {  

                    e.printStackTrace();  

                }  

            }  

        }  

        return httpStr;  

    }  

    /** 

     * 发送 POST 请求(HTTP),JSON形式 

     * @param apiUrl 

     * @param json json对象 

     * @return 

     */  

    public static String doPost(String apiUrl, Object json) {  

        CloseableHttpClient httpClient = HttpClients.createDefault();  

        String httpStr = null;  

        HttpPost httpPost = new HttpPost(apiUrl);  

        CloseableHttpResponse response = null;  

        try {  

            httpPost.setConfig(requestConfig);  

            StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");//解决中文乱码问题  

            stringEntity.setContentEncoding("UTF-8");  

            stringEntity.setContentType("application/json");  

            httpPost.setEntity(stringEntity);  

            response = httpClient.execute(httpPost);  

            HttpEntity entity = response.getEntity();  

            System.out.println(response.getStatusLine().getStatusCode());  

            httpStr = EntityUtils.toString(entity, "UTF-8");  

        } catch (IOException e) {  

            e.printStackTrace();  

        } finally {  

            if (response != null) {  

                try {  

                    EntityUtils.consume(response.getEntity());  

                } catch (IOException e) {  

                    e.printStackTrace();  

                }  

            }  

        }  

        return httpStr;  

    }  

    /** 

     * 发送 SSL POST 请求(HTTPS),K-V形式 

     * @param apiUrl API接口URL 

     * @param params 参数map 

     * @return 

     */  

    public static String doPostSSL(String apiUrl, Map<String, Object> params) {  

        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();  

        HttpPost httpPost = new HttpPost(apiUrl);  

        CloseableHttpResponse response = null;  

        String httpStr = null;  

        try {  

            httpPost.setConfig(requestConfig);  

            List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size());  

            for (Map.Entry<String, Object> entry : params.entrySet()) {  

                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry  

                        .getValue().toString());  

                pairList.add(pair);  

            }  

            httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8")));  

            response = httpClient.execute(httpPost);  

            int statusCode = response.getStatusLine().getStatusCode();  

            if (statusCode != HttpStatus.SC_OK) {  

                return null;  

            }  

            HttpEntity entity = response.getEntity();  

            if (entity == null) {  

                return null;  

            }  

            httpStr = EntityUtils.toString(entity, "utf-8");  

        } catch (Exception e) {  

            e.printStackTrace();  

        } finally {  

            if (response != null) {  

                try {  

                    EntityUtils.consume(response.getEntity());  

                } catch (IOException e) {  

                    e.printStackTrace();  

                }  

            }  

        }  

        return httpStr;  

    }  

    /** 

     * 发送 SSL POST 请求(HTTPS),JSON形式 

     * @param apiUrl API接口URL 

     * @param json JSON对象 

     * @return 

     */  

    public static String doPostSSL(String apiUrl, Object json) {  

        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();  

        HttpPost httpPost = new HttpPost(apiUrl);  

        CloseableHttpResponse response = null;  

        String httpStr = null;  

        try {  

            httpPost.setConfig(requestConfig);  

            StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");//解决中文乱码问题  

            stringEntity.setContentEncoding("UTF-8");  

            stringEntity.setContentType("application/json");  

            httpPost.setEntity(stringEntity);  

            response = httpClient.execute(httpPost);  

            int statusCode = response.getStatusLine().getStatusCode();  

            if (statusCode != HttpStatus.SC_OK) {  

                return null;  

            }  

            HttpEntity entity = response.getEntity();  

            if (entity == null) {  

                return null;  

            }  

            httpStr = EntityUtils.toString(entity, "utf-8");  

        } catch (Exception e) {  

            e.printStackTrace();  

        } finally {  

            if (response != null) {  

                try {  

                    EntityUtils.consume(response.getEntity());  

                } catch (IOException e) {  

                    e.printStackTrace();  

                }  

            }  

        }  

        return httpStr;  

    }  

    /** 

     * 创建SSL安全连接 

     * 

     * @return 

     */  

    private static SSLConnectionSocketFactory createSSLConnSocketFactory() {  

        SSLConnectionSocketFactory sslsf = null;  

        try {  

            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {  

                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {  

                    return true;  

                }  

            }).build();  

            sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {  

                @Override  

                public boolean verify(String arg0, SSLSession arg1) {  

                    return true;  

                }  

                @Override  

                public void verify(String host, SSLSocket ssl) throws IOException {  

                }  

                @Override  

                public void verify(String host, X509Certificate cert) throws SSLException {  

                }  

                 @Override  

                public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {  

                }  

            });  

        } catch (GeneralSecurityException e) {  

            e.printStackTrace();  

        } 

return sslsf;  

    }  

/** 

     * 测试方法 

     * @param args 

     */  

    public static void main(String[] args) throws Exception {

    String apiUrl = "请求URL";

HashMap<String, Object> params = new HashMap<String, Object>();

    String sendtime = null;	/*new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a").format(new Date());*/

String reqtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a").format(new Date());

String sendMsg = "欢迎您注册象聚金元,您的注册验证码为:{$var},如非本人操作,可忽略本短信。成功注册后您将获得{$var}元新手体验金!";

    System.out.println(sendMsg);

    params.put("account", "敏感信息");

    params.put("password", " 敏感信息 ");

    params.put("msg", sendMsg);

params.put("params","176****1716,233441,1288.00;155***6033,233442,1288.00");

// 定时发送 时间格式 yyyyMMddHHmm

if (sendtime == null) {

params.put("sendtime",

new SimpleDateFormat("yyyyMMddHHmm").format(new Date()));

} else {

params.put("sendtime", 请求报文中的请求日期时间);

}

    params.put("report", "false");

JSONObject json = new JSONObject(params);

String send = json.toString();

System.out.println(send);

        // 返回值

        String respon = HttpUtil.doPost(apiUrl, send);

    }  

}

本测试demo仅用于接口调用测试用,敏感信息已屏蔽~~~

    现在主要就是群发接口的记表,需要解析出params的内容数据,循环记表。得到异步通知结果更新表记录的状态。(重点)

大致的设计如次,下周开始实际的开发了,希望一切顺利!按照预期需求时间完成,不加班不加班不加班。。。


对了,自己参与开发的这个理财项目,也是开发了一年多的项目,欢迎注册(注册就可以了哈哈哈哈)。有钱的大佬可以去买理财,高收益,地址:https://www.xiangcapital.com/

安卓和IOS都已经上线:【象聚金元】

#################################################################

后期如有新的心得,持续更新中。。。


posted @ 2022-04-01 18:08  鸟不拉诗  阅读(225)  评论(0编辑  收藏  举报