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完成了给买家发送邮件的功能,还遗留一个功能,就 ...
随机推荐
- 《OpenGL超级宝典》编程环境配置
最近在接触OpenGL,使用的书籍就是那本<OpenGL超级宝典>,不过编程环境的搭建和设置还是比较麻烦的,在网上找了很多资料,找不到GLTools.lib这个库.没办法自己就借助源码自己 ...
- CRC32加密算法原理
[转]:https://blog.csdn.net/android_mnbvcxz/article/details/78902737
- 如何让多个android listview同时使用一个滚动条
如何让多个android listview同时使用一个滚动条 重新设置ListView的高度 /** * 设置listview高度,注意listview子项必须为LinearLayout才能调用该方法 ...
- 再议GCC编译时的静态库依赖次顺问题
假设有如三个源代码文件: $ cat a.cpp void a() { } $ cat b.cpp extern void a(); void b() { a(); // 调用a.cpp中的a() } ...
- ERROR Function not available to this responsibility.Change responsibilities or contact your System Administrator.
APPLIES TO: Navigation: Help > Diagnostics > Custom Code > Personalize or Help > Diag ...
- Python学习-5.Python的变量与数据类型及字符串的分割与连接
在Python中,变量类型是固定的,一旦声明就不能修改其类型(在Python里感觉不应该用声明,而应该用使用) 正确: var = 1 print(var) var = 2 print(var) 依次 ...
- centos mysql忘记密码找回(仅限mysql5.7)
1.停掉mysql 2.执行#mysqld_safe --user=mysql --skip-grant-tables --skip-networking & 3.#mysql 4.updat ...
- 【转发】在SQL Server中通过字段值查询存储该字段的表
-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved. -- Purpose: To search all colu ...
- 常用脚本--生成Agent Job的创建脚本
USE [master] GO /****** Object: StoredProcedure [dbo].[DumpJobsql] Script Date: 02/07/2014 11:38:46 ...
- C#——获取远程xml文件
/// <summary> /// 加载远程XML文档 /// </summary> /// <param name="URL"></pa ...