做了几个调用三方短信平台发送短信的例子,大部分需要 携带参数,向指定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. SpringBoot Redis 2.0.x

    redis的安装 在笔者之前的文章中有介绍redis的安装,不会的可以去看 笔者之前写的文章redis安装 完成安装后如果不熟悉redis的操作,redis官方文档也有基本操作指南,redis基本操作 ...

  2. spring data jpa执行update和delete语句时报错处理

    之前项目中使用spring data jpa时,遇到删除记录的需求时,主要利用spring data中自带的delete()方法处理,最近在dao层使用delete sql语句时报错,代码如下: @Q ...

  3. cobbler安装4个报错汇总及解决方法:ImportError

    安装完,检查cobbler:cobbler check发现这个问题ImportError: No module named yaml 具体报错如下: [root@www localdisk]# cob ...

  4. netcore3.1 + vue (前后端分离)Excel导入

    1.前端(vue)代码 2.公共类ExcelHelper 3.后端(netcore)代码 思路:导入类似于上传,将excel上传后将流转换为数据 1.前端(Vue)代码 这里使用的是ElementUI ...

  5. Hive源码上手及问题解决

    一.编译准备 1.下载源码包 https://github.com/apache/hive/archive/refs/tags/rel/release-2.3.7.zip 或使用git直接拉取 无法解 ...

  6. Java刷题常用API

    目录 输入输出 快速查看 最大最小值 string stringbuilder 集合 map queue stack set 优先队列 PriorityQueue (Heap) 数组 静态数组 动态数 ...

  7. String、StringBuilder和StringBuffer的比较

    目录 1.String特性 1.1 不可变 1.2 字符串常量池 2.StringBuilder和StringBuffer 2.1 区别 2.2 应用场景 1.String特性 1.1 不可变 它是I ...

  8. PYTHON IDLE同时运行两个PY,互不影响

    1.打开指定文件夹 2.右击a1.py,用IDLE打开(idle1) 3.右击a2.py,用IDLE打开(idle2) 4.则分别按F5运行,则两个互不影响. 5.再用IDLE1打开新程序,用IDLE ...

  9. Motion Planning 是什么

    前言与引用 这一个呢,主要是自己突然看一篇论文的时候不知道 为什么他提出的方法对于规划来说就是好的,规划又应该分为哪几个部分,解决的是哪几个部分的问题?带着这个问题,我就去搜:Motion Plann ...

  10. 【LeetCode】27.移除元素

    27.移除元素 知识点:数组:双指针:: 题目描述 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不要使用额外的数组空间,你必须 ...