SpringBoot 整合 中国移动 MAS HTTP1.0 实现短信发送服务
因为客户需要,本身使用的 阿里云的短信服务改为了中国移动MAS HTTP 1.0 短信通知,因为看到网络上关于此类的博客知识很少,再趟完坑后特地写下这篇博客,提醒后来人。
特别感谢 中国移动MAS 客服 @左立,可能你看不到,非常感谢你 不厌其烦的回答!!
首先创建 接口,用户类型是HTTP

然后下载文档,下载签名:

这里简单说一下流程: HTTP 1.0 的通讯方式是,
1. 先向中国移动 发送 企业名、接口名、接口密码,实现登录操作。中国移动返回登录id 和密钥。
2. 携带中国移动返回的密钥和 所需要的信息进行第二次的 请求,此次请求就是发送短信的请求。
根据文档书写所需要的发送短信的工具类:
public class HttpSend {
private static String ec_name = "山东*****" ; // 企业名
private static String user_name = "***" ; // 接口账号
private static String user_passwd = "****" ; // 接口账号密码
private static String sign = "*****" ; //签名编号
private static String serial = "" ; // 扩展码
private static String checkUrl = "http://mas.ecloud.10086.cn/app/http/authorize" ; // 身份验证url
private static String sendUrl = "http://mas.ecloud.10086.cn/app/http/sendSms" ; // 发送信息的url
// 身份验证方法
public static CheckRes check (){
String req = "ec_name="+ec_name+"&user_name="+user_name+"&user_passwd="+user_passwd ;
System.out.println("传入参数:"+req);
HttpRequest httpRequest = new HttpRequest() ;
String checkStr = httpRequest.sendPost(checkUrl,req) ; //返回验证信息的 回参
System.out.println("验证身份结果:"+checkStr);
CheckRes checkRes = JSONUtils.json2pojo(checkStr,CheckRes.class);
String mas_user_id = checkRes.getMas_user_id() ;
System.out.println("mas_user_id:"+mas_user_id);
return checkRes ;
}
// 发送短信 方法,需要使用到 check()方法的 返回值 CheckRes
public static Boolean send (CheckRes checkRes ,String mobiles ,String content){
String temporary = checkRes.getMas_user_id() + mobiles + content + sign + serial + checkRes.getAccess_token() ; // 存放要进行加密的信息
String mac = MD5Util.getMD5Up(temporary) ; //加密
String sendReq = "mas_user_id="+checkRes.getMas_user_id()+"&mobiles="+mobiles+"&content="+content+"&sign="+sign+"&serial="+serial+"&mac="+mac;
HttpRequest httpRequest = new HttpRequest() ;
String sendStr = httpRequest.sendPost(sendUrl,sendReq) ; //发送 普通短信
System.out.println("发送结果:"+sendStr);
String[] test = sendStr.split(",",0); // 将字符串 按照 逗号分隔,取前面一段
if (test[0].equals("{\"RET-CODE\":\"SC:0000\"")){ // 直接进行比较
return true ;
}else {
return false ;
}
}
// 测试 main函数
public static void main(String[] args){
CheckRes result = check() ;
Boolean b =send(result,"15610446589","益羊铁路测试短信");
if (b){
System.out.println("成功");
}else {
System.out.println("失败");
}
}
}
这里用到的工具 HttpRequest ,用于携带参数请求页面:
public class HttpRequest {
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
// conn.setRequestProperty("accept", "*/*");
// conn.setRequestProperty("connection", "Keep-Alive");
// conn.setRequestProperty("user-agent",
// "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
}
JSONUtils工具:
public class JSONUtils {
private final static ObjectMapper objectMapper = new ObjectMapper();
private static Logger log = LoggerFactory.getLogger(JSONUtils.class);
private JSONUtils() {
}
public static ObjectMapper getInstance() {
return objectMapper;
}
public static String obj2json(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
log.error(e.getMessage());
}
return null;
}
public static <T> T json2pojo(String jsonStr, Class<T> clazz) {
try {
return objectMapper.readValue(jsonStr, clazz);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
log.error(e.getMessage());
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
MD5工具,加密使用大写的 MD5加密方式
public class MD5Util {
public static String getMD5(String value) {
String s = null;
char hexDigits[] = { // 用来将字节转换成 16 进制表示的字符
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
'd', 'e', 'f'};
try {
java.security.MessageDigest md = java.security.MessageDigest
.getInstance("MD5");
md.update(value.getBytes());
// MD5 的计算结果是一个 128 位的长度整数,
byte tmp[] = md.digest();
// 用字节表示就是 16 个字节
char str[] = new char[16 * 2]; // 每个字节用 16 进制表示的话,使用两个字符,
// 所以表示成 16 进制需要 32 个字符
int k = 0; // 表示转换结果中对应的字符位置
for (int i = 0; i < 16; i++) { // 从第一个字节开始,对 MD5 的每一个字节
// 转换成 16 进制字符的转换
byte byte0 = tmp[i]; // 取第 i 个字节
str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字节中高 4 位的数字转换,
// >>> 为逻辑右移(即无符号右移),将符号位一起右移
// 取字节中低 4 位的数字转换
str[k++] = hexDigits[byte0 & 0xf];
}
s = new String(str); // 换后的结果转换为字符串
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
// MD5大写
public static String getMD5Up(String value) {
String s = null;
char hexDigits[] = { // 用来将字节转换成 16 进制表示的字符
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
'D', 'E', 'F'};
try {
java.security.MessageDigest md = java.security.MessageDigest
.getInstance("MD5");
md.update(value.getBytes());
// MD5 的计算结果是一个 128 位的长度整数,
byte tmp[] = md.digest();
// 用字节表示就是 16 个字节
char str[] = new char[16 * 2]; // 每个字节用 16 进制表示的话,使用两个字符,
// 所以表示成 16 进制需要 32 个字符
int k = 0; // 表示转换结果中对应的字符位置
for (int i = 0; i < 16; i++) { // 从第一个字节开始,对 MD5 的每一个字节
// 转换成 16 进制字符的转换
byte byte0 = tmp[i]; // 取第 i 个字节
str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字节中高 4 位的数字转换,
// >>> 为逻辑右移(即无符号右移),将符号位一起右移
// 取字节中低 4 位的数字转换
str[k++] = hexDigits[byte0 & 0xf];
}
s = new String(str); // 换后的结果转换为字符串
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
/**
* 判断字符串的md5校验码是否与一个已知的md5码相匹配
*
* @param md5 要校验的字符串
* @param md5PwdStr 已知的md5校验码
*/
public static boolean checkPassword(String md5, String md5PwdStr) {
return md5.equals(md5PwdStr);
}
}
这里注意的是 ,这两次的请求都是 post 请求。
要注意拼接字符串以及加密的字符串 的顺序是不能乱的!!
最后再次感谢 @左立
SpringBoot 整合 中国移动 MAS HTTP1.0 实现短信发送服务的更多相关文章
- Springboot 整合 中国移动MAS HTTP1.0 实现短信发送服务(二)
原因:身份验证传入的参数包含中文企业名,因为本地编码格式是支持中文的:而客户的服务器中文却乱码,导致传给中国移动MAS服务器的是乱码的信息. 解决:非常简单,将中文信息转为UTF-8.例如(%E5%8 ...
- c#简单易用的短信发送服务 悠逸企业短信服务
悠逸企业短信发送服务,是一种比较简单易操作的短信发送服务,使用POST的方式,请求相应地址就可以实现短信发送功能 1 /// <summary> /// 短信发送服务 /// </ ...
- 4、下行短信发送WebService、下行短信发送服务 -功能详细设计 --短信平台
3. 下行短信发送WebService 开发一个WebService,供第三方系统调用,用于发送短信.WebService接收数据后,将信息存储入数据库的短信发送数据表中. WebService参数 ...
- 阿里云短信发送服务SDK-Python3
本文提供阿里云的短信发送服务SDK,使用Python3实现. # -*- coding: utf-8 -*- # pip install requests import requests import ...
- PHP短信发送服务 youe短信企业服务
/** * 通用短信平台HTTP接口POST方式发送短信实例 * 返回字符串 * 一般情况下调用此方法 */ function postSendMessage($msgContents,$phoneL ...
- thinkphp 5.0整合阿里大于验证码短信发送接口,含完整模型验证实例DEMO
为大家分享一个阿里大于短信发送接口: 首先创建一个发送模型(Send.php): <?php namespace app\index\model; use think\Validate; cla ...
- java springboot activemq 邮件短信微服务,解决国际化服务的国内外兼容性问题,含各服务商调研情况
java springboot activemq 邮件短信微服务,解决国际化服务的国内外兼容性问题,含各服务商调研情况 邮件短信微服务 spring boot 微服务 接收json格式参数 验证参数合 ...
- SpringBoot @Async 异步处理业务逻辑和发短信逻辑
有个业务场景,业务数据审核通过后需要给用户发短信,发短信过程比较耗时,可能需要几秒甚至十几秒,因此使用异步发短信 使用了注解@Async来实现: 1.SpringApplication启用注解@Ena ...
- 【SSH网上商城项目实战26】完成订单支付后的短信发送功能
转自: https://blog.csdn.net/eson_15/article/details/51475431 上一节我们使用了Java mail完成了给买家发送邮件的功能,还遗留一个功能,就 ...
随机推荐
- 简单拼接图像的tile_images和tile_images_offset算子
有时候通常需要简单的拼图,不涉及图像融合之类的,仅仅是简单的平移将多张图拼接成一张图.tile_images和tile_images_offset就是用于简单拼图的2个算子. 谈到拼图,肯定有以下问题 ...
- SystemTap 内核调试
一.简介 Systemtap是一个Linux下的全新的调式.诊断和性能测量工具,是我目前所知的最强大的内核调试工具. 参考: http://m.blog.csdn.net/blog/hnllei/75 ...
- centos7 redis伪集群安装
安装gcc: yum install gcc -y 上传redis软件包到 /home下 解压: tar xf redis-3.2.11.tar.gz 进入 redis 目录 : cd r ...
- 在VMware中设置CentOS7的网络
为了能够使用XShell来管理我们安装好的CentOS7系统,所以我们要先设置CentOS7的网络使其能够联网. 1.选择vmware的编辑,然后点击虚拟网络编辑器 2.点击更改设置(需要有 ...
- ios9出现的问题
升级后需要注意两个地方 1 在build Settings 搜索bitcode 设置成no 2 在info.plist里添加以下属性 程序中报错: App Transport Security ...
- java try catch finally return执行
public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i ...
- JAVA常见面试题及解答
JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...
- WinExec打开exe文件
1,WinExec(): WinExec主要运行EXE文件,不能运行其他类型的文件.不用引用特别单元. 原型:UINT WinExec(exePath,ShowCmd) 示例,我想要用记事 ...
- FIREDAC(DELPHI10 or 10.1)提交数据给ORACLE数据库的一个不是BUG的BUG
发现FIREDAC(DELPHI10 or 10.1)提交数据给ORACLE数据库的一个不是BUG的BUG,提交的表名大小写是敏感的. 只要有一个表名字母的大小写不匹配,ORACLE就会认为是一个不认 ...
- day14(带参装饰器,迭代器,生成器,枚举对象)
一,复习 ''' 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 ...