做了几个调用三方短信平台发送短信的例子,大部分需要 携带参数,向指定URL发送请求

回顾对接第一个平台时痛苦的乱码经历,这里放一份代码,算是个模版,再用到的时候过来copy一下就OK。

在进入主题之前,考虑一个编码的问题:

1、unicode,utf8,gbk,gb2312之类的指的到底是什么?为什么需要它们?

字符编码中ASCII、Unicode和UTF-8的区别 - 风行风中 - 博客园 (cnblogs.com)

GB2312、GBK、GB18030 这几种字符集的主要区别是什么? - 知乎 (zhihu.com)

  • 简单来说,计算机只能识别0和1组成的二进制,所以为了显示某一个字符,必须指定字符与二进制表示的对应关系。
  • 各种各样的字符会组合成一个集合,集合被称为字符表,
  • 给字符表里的字符编上一个数字,也就是字符集合到一个整数集合的映射,这个整数集合叫做字符集,而按照字符二进制表示标准进行的实现叫做编码,我们需要它们的结合来让屏幕显示出我们看得懂的内容。
  • 编码其实就是一种映射关系,将字节表示的值映射到字符集中的符号。
  • unicode是一种字符集,涵盖了世界上所有的字符,utf8是一种用于unicode的编码方式
  • gb2312是国内针对 ASCII 扩展的字符集,通常我们把编码方案也叫做gb2312。GBK是对gb2312做的扩展。

​ 也就是说,gbk,gb2312和 utf8 不是一个派系的。

2、程序运行时,处于内存中的字符串是不是也具有指定的编码?如果没有,为什么有时候在获取字节数组时还要指定编码方式?

这里我看了一些文章,有了自己的理解,但是不知道理解的是否正确,先不列出来了


Get请求

  • getResponse 内将数据写入请求的方式
  • 组织数据时对content进行URL编码
  • 正确设置content-type
//调用处捕获异常处理发送失败的情况,所以代码内不合预期的情况都是直接抛Exception
public void send(String to, String content) throws Exception { //username,password,content,to...参数的非空 及 格式判断 String apiRspStr = getResponse(to,content); //构建请求,获取响应 String result = resolve(apiRspStr); //解析响应数据(kv,json,html...),
//成功时返回代码,失败时返回错误消息 if(!"0".equals(result)) { //"0" 需要按平台文档替换
throw new Exception("消息发送失败:" + result);
}
} private String getResponse(String to, String content) throws Exception {
URLConnection con = null;
OutputStreamWriter out = null;
BufferedReader br = null;
String sendSmsData; try {
sendSmsData = organizationData(to,content);
log.info("请求参数为:" + sendSmsData);
} catch (Exception e) {
log.error("组织请求数据时出现错误", e);
throw e;
} try {
URL requestUrl = new URL(getUrl());
con = requestUrl.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Pragma", "no-cache");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=gb2312"); // 按短信平台的要求设置 charset的值 out = new OutputStreamWriter(con.getOutputStream());
out.write(sendSmsData);
out.flush();
out.close(); br = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = "";
StringBuffer buf = new StringBuffer();
while ( (line = br.readLine()) != null ) {
buf.append(line);
}
String responseStr = buf.toString();
log.info("响应数据:" + responseStr); return responseStr;
} catch (IOException e) {
e.printStackTrace();
log.error("获取响应失败", e);
throw e;
} finally {
try {
if(out != null) {
out.close();
}
}catch(Exception e) {}
try {
if(br != null) {
br.close();
}
}catch(Exception e) {}
}
} private String organizationData(String to, String content) throws Exception {
StringBuilder sendBuilder = new StringBuilder();
sendBuilder.append("username=");//用户登录名
sendBuilder.append(getUserName()); sendBuilder.append("&password=");//密码需要按平台要求处理;
sendBuilder.append(hashpwd()); sendBuilder.append("&mobiles=");//接收手机号,限定不允许
sendBuilder.append(to); sendBuilder.append("&content=");
sendBuilder.append(URLEncoder.encode(content, "GB2312")); return sendBuilder.toString();
} // resolve方法 依赖于短信平台返回结果的标准,这里提供的内容脱离平台就没有意义
//示例代码内 发送成功result为0,发送失败会返回各种含义的数字,description是中文描述
private String resolve(String rspStr) throws Exception { //rspStr: result=0&description=%B7%A2%CB%CD%B3%C9%B9%A6&faillist= String[] resultArray = rspStr.split("&");
Map kv = new HashMap();
for(String array : resultArray) {
String[] elementArray = array.split("=");
if(elementArray.length == 2) {
kv.put(elementArray[0], elementArray[1]);
}
}
if(kv.isEmpty()) {
log.error("rspStr: " + rspStr);
throw new Exception("解析返回数据时未得到结果");
}
String result = "";
if("0".equals(kv.get("result").toString())) {
result = "0";
return result;
}
result = URLDecoder.decode(kv.get("description").toString(),"gb2312") ;
return result;
}

Post请求

  • 短信内容要用URL编码
  • 写入请求体的数据以 List<NameValuePair> 形式组织
 public void sendSmsPost(MsgData msgData){

        String respContent;//响应报文
CloseableHttpClient httpClient = null;
try{
httpClient = HttpClients.createDefault(); //创建连接对象
HttpPost httpPost = new HttpPost(smsUrl); //创建post对象
Map params = new HashMap(); //构建请求参数 String phone = msgData.getMsgTo(); //接收手机号
String text = msgData.getContent(); //发送内容
String gbkText = URLEncoder.encode(msgData.getContent().trim(), "GBK");
System.out.println("短信内容GBK:" + gbkText);
params.put("username",username);//登录用户名
params.put("password",password);//登录用户密码
params.put("to",phone); //消息接收手机号码
params.put("text",gbkText); List<NameValuePair> postParams = getParams(params); httpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=gbk");
httpPost.setEntity(new UrlEncodedFormEntity(postParams));
//发送http请求,获取返回结果
HttpResponse httpResponse = httpClient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == 200){
//解析数据
respContent = EntityUtils.toString(httpResponse.getEntity());
System.out.println("响应数据:" + respContent);
}else {
//请求失败
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(httpClient != null){
httpClient.close();
}
}catch (Exception e2){
e2.printStackTrace();
}
}
} /**
* 参数解析
* @param map
* @return
*/
public static List<NameValuePair> getParams(Map<String, String> map){
List<NameValuePair> params = new ArrayList<NameValuePair>();
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> e : entrySet) {
String name = e.getKey();
String value = e.getValue();
NameValuePair pair = new BasicNameValuePair(name, value);
params.add(pair);
}
return params;
}

JAVA 调用第三方短信平台接口发送短信的更多相关文章

  1. java 调用短信 api 接口发送短信

    参考:   https://blog.csdn.net/u014793522/article/details/59062014 参考 :https://blog.csdn.net/Lu_shilusi ...

  2. Java之HttpClient调用WebService接口发送短信源码实战

    摘要 Java之HttpClient调用WebService接口发送短信源码实战 一:接口文档 二:WSDL 三:HttpClient方法 HttpClient方法一 HttpClient方法二 Ht ...

  3. Java调用第三方http接口的方式

    1. 概述 在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适.很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信.天气等). 在J ...

  4. 短信平台软件开发,短信发送平台销售,短信软件源码,G客短信发送平台

    一:web短信平台组成  需要短信软件平台源码的联系QQ:290615413 vx:290615413  整套短信系统平台还是由B/S(客户端+后台,取消了以前C/S的管理后台) ,C/S发送服务端和 ...

  5. 企业短信通 C# HTTP接口 发送短信

    /* 功能: 企业短信通 C# HTTP接口 发送短信 修改日期: 2014-09-01 说明: http://api.cnsms.cn/?ac=send&uid=用户账号&pwd=M ...

  6. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  7. java调用C# webService发布的接口

    java调用C# webService发布的接口 java调用C# webService方式有很多种我这里只介绍一种 首先需要引入axis的jar包 axis的maven坐标如下 <depend ...

  8. c# 调用短信平台接口,给手机发送短信

    项目上要做个发手机短信的功能.网上找找了,用的微米的短信接口. 注册后,获得UID和UID key,C#代码中需要这个 调用代码很简单 ", con = "[微米]您的验证码是:6 ...

  9. android 中调用接口发送短信

    android中可以通过两种方式发送短信 第一:调用系统短信接口直接发送短信:主要代码如下: //直接调用短信接口发短信 SmsManager smsManager = SmsManager.getD ...

随机推荐

  1. [Usaco2018 Dec]Teamwork 题解

    题目描述 题目描述 在Farmer John最喜欢的节日里,他想要给他的朋友们赠送一些礼物.由于他并不擅长包装礼物,他想要获得他的 奶牛们的帮助.你可能能够想到,奶牛们本身也不是很擅长包装礼物,而Fa ...

  2. layui 点击按钮 界面会刷新问题

    将button 改为input: <input class="layui-btn" type="button" style="border:so ...

  3. Java数据库开发(三)之——补充

    一.SQL注入与防范 使用PreparedStatement替代Statement对象,它提供了参数化SQL的方式 二.事务 定义 事务是并发控制的基本单位,满足ACID特征 原子性:atomicit ...

  4. Linux云计算-04_Linux用户及权限管理

    Linux是一个多用户的操作系统,引入用户,可以更加方便管理Linux服务器,系统默认需要以一个用户的身份登录,而且在系统上启动进程也需要以一个用户身份器运行,用户可以限制某些进程对特定资源的权限控制 ...

  5. Linux基础 -03

    2.2.3 head-tail 命令 #------head #head pass #查看头部内容,默认前10行 #head -n5 pass #查看头部前5行,使用-n指定 #-------tail ...

  6. Spring-Redis缓存业务优化(通配符删除、两种自定义缓存时长)

    application.yml配置 spring:    cache:     type: REDIS     redis:       time-to-live: PT300S # 默认缓存秒数   ...

  7. Sqlite3:Sqlite3命令行Linux操作

    1.查看sqlite版本 [istester@ietester.com idoxu]$ sqlite3 -version 2.进入sqlite后台操作 指定一个完整文件的路径名,打开或者创建数据库(文 ...

  8. shiro框架基础

    一.shiro框架简介 Apache Shiro是Java的一个安全框架.其内部架构如下: 下面来介绍下里面的几个重要类: Subject:主体,应用代码直接交互的对象就是Subject.代表了当前用 ...

  9. SpringBoot | 2.1 SpringBoot自动装配原理

    @ 目录 前言 1. 引入配置文件与配置绑定 @ImportResource @ConfigurationProperties 1.1 @ConfigurationProperties + @Enab ...

  10. c语言:getchar() getch()回显

    //getch() 不回显函数,当用户按下某个字符时,函数自动读取,无需按回车 //所在头文件:conio.h 从控制台读取一个字符,但不显示在屏幕上 //int getchar() //头文件:#i ...