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完成了给买家发送邮件的功能,还遗留一个功能,就 ...
随机推荐
- WPF设置Window的数据上下文(DataContext)为自身
WPF设置Window的数据上下文(DataContext)为自身的XAML: DataContext="{Binding RelativeSource={RelativeSource Se ...
- Java 设计模式系列(二三)访问者模式(Vistor)
Java 设计模式系列(二三)访问者模式(Vistor) 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以 ...
- UVaLive 4128 Steam Roller (多决策最短路)
题意:给定一个图,r 根横线, c 根竖线.告诉你起点和终点,然后从起点走,每条边有权值,如果是0,就表示无法通行.走的规则是:如果你在下个路要转弯,会使这段路的时间加倍,但是如果一条路同时是这样,那 ...
- idea jvm 优化
修改对应配置文件 64位的是idea64.exe.vmoptions -Xms2048m -Xmx2048m -Xmn1024m -XX:PermSize=512m -XX:MaxPermSize=5 ...
- Linq编译带来的诡异错误
今天遇到一个很诡异的问题,初步猜测是Linq编译以及编译器自动优化带来的原因,对IL不是很熟悉,所以懒得去追了. 贴个代码出来,希望能抛砖引玉,得到正解. 注意到我用原始的foreach语句代替了li ...
- 利用ROW_NUMBER中的partition by 删除重复Key的数据
With temp As ( Select ROW_NUMBER() over(partition by LogisticsPlan order by createon) rowID,ID from ...
- Rsyslog远程传输的几种方式
基本介绍 Rsyslog是一个syslogd的多线程增强版,rsyslog vs. syslog-ng 链接是rsyslog官方和syslog特性和性能上的一些对比,目前大部分Linux发行版本默认也 ...
- postgresql 修改配置生效方法
对于配置服务器,,太多时候我们在Linux中做的操作是,配置*.conf文件,然后重启服务.而很多服务都具有reload功能,而但是具体到某个配置,有时候直接说出需不需要重启服务而使得配置生效,这并不 ...
- 使用pscp/pslurp批量并发分发/回收文件
pssh pssh -h ip文件 本地文件 远程目录或文件 pslurp pslurp -h ip文件 -L 本地目录 远程文件 本地文件名称
- Bootstrap变形记
bootstrap审美疲劳了,想个招换换样子,THINKING... 变形 >>> 哈,不用改已有代码,添加我的Harley.js即可,有空在玩... 真实好久不玩博客园了,200字 ...