最新一个个性化项目,客户要求使用阿里云短信发送接口。

但是实在不想引入阿里云的SDK,就自己生成签名,拼接URL实现,  其实用他们的SDK最终也是一哥GET请求进行调用,归根接底还是HTTP请求。

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.net.UnknownServiceException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;import sun.misc.BASE64Encoder;import com.commnetsoft.PropertyEnum;
import com.commnetsoft.BaseErrorCode.Base;
import com.commnetsoft.admin.model.sys.Messagequeue;
import com.commnetsoft.admin.model.sys.MsgApi;
import com.commnetsoft.admin.service.sys.MsgApiService;
import com.commnetsoft.core.SpringContext;
import com.commnetsoft.spi.IErrorCode;
import com.commnetsoft.spi.exception.ServiceUnavailableException;
import com.commnetsoft.util.HttpUtil;
import com.commnetsoft.util.SerializerUtil;/*** 阿里云短信发送实现* @author wangyijie* @date 2018年1月10日* @version 1.0*/
@Service
public class AliyunSendMsg extends AbstractSendSMS<Messagequeue> {private final static Logger logger = LoggerFactory.getLogger(AliyunSendMsg.class);private MsgApiService msgApiService = SpringContext.getBean("msgApiService");@Overridepublic String getName() {return "阿里云短信发送";}@Override@SuppressWarnings("unchecked")public IErrorCode doSend(Messagequeue msg) throws ServiceUnavailableException,MalformedURLException, UnknownServiceException, IOException {String accessKeyId = PropertyEnum.ALIYUN_SENDMSG_ACCESSKEYID.getValue();if (StringUtils.isBlank(accessKeyId)) {logger.error("阿里云短信发送未配置,需要在系统设置——阿里云短信发送设置中填入accessKeyId");return Base.FAIL;}String accessSecret = PropertyEnum.ALIYUN_SENDMSG_ACCESSSECRET.getValue();if (StringUtils.isBlank(accessSecret)) {logger.error("阿里云短信发送未配置,需要在系统设置——阿里云短信发送设置中填入accessSecret");return Base.FAIL;}String param = msg.getContent();//现将内容序列化成mapMap<String, String> paramMap = SerializerUtil.deserializeObj(param, Map.class);if (paramMap == null || paramMap.size() < 1) {logger.error("阿里云短信发送失败——不合法的参数!参数={}", param);return Base.FAIL;}//获取设置的短信签名String signName = paramMap.get("signName");if (StringUtils.isBlank(signName)) {logger.error("阿里云短信发送失败——参数中未设置signName!参数={}", param);return Base.FAIL;}//获取设置的短信模板IDString templateCode = paramMap.get("templateCode");if (StringUtils.isBlank(templateCode)) {logger.error("阿里云短信发送失败——参数中未设置templateCode!参数={}", param);return Base.FAIL;}//获取要发送的内容String content = paramMap.get("content");if (StringUtils.isBlank(content)) {logger.error("阿里云短信发送失败——参数中未设置要发送的内容!参数={}", param);return Base.FAIL;}//目标手机号String phone = msg.getTargetPhone();/*** 设置参数*/SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); //设置时区df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));Map<String, String> paras = new HashMap<String, String>();//固定参数paras.put("SignatureMethod", "HMAC-SHA1");//用于请求的防重攻击,每次请求唯一,用:java.util.UUID.randomUUID()生成paras.put("SignatureNonce", UUID.randomUUID().toString());//阿里云分配的用户唯一IDparas.put("AccessKeyId", accessKeyId);//固定值:1.0paras.put("SignatureVersion", "1.0");//格式化后的当前时间(时间与阿里云服务器时间相差15分钟会被拒绝请求)paras.put("Timestamp", df.format(new Date()));//返回参数格式(可选JSON/XML)paras.put("Format", "JSON");//API的命名,固定值paras.put("Action", "SendSms");//API的版本,固定值paras.put("Version", "2017-05-25");//API支持的RegionIDparas.put("RegionId", "cn-hangzhou");//短信接收号码,支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式paras.put("PhoneNumbers", phone);//短信签名(用户账号可新增签名,需审批)paras.put("SignName", signName);//短信模板变量替换JSON串,如果JSON中需要带换行符,参照标准的JSON协议。  如:{“code”:”1234”,”product”:”ytx”}    {\"customer\":\"nihao\"}paras.put("TemplateParam", content);    //短信模板ID(可自定义,但是需要审批)paras.put("TemplateCode", templateCode);//获取阿里云发送短信的服务器地址Integer msgApiId = getMsgapiid();MsgApi msgApi = msgApiService.queryById(msgApiId);String aliyunUrl = msgApi.getHttpurl();//参数KEY排序TreeMap<String, String> sortParas = new TreeMap<String, String>();sortParas.putAll(paras);try {//构造待签名的字符串Iterator<String> it = sortParas.keySet().iterator();StringBuilder sortQueryStringTmp = new StringBuilder();while (it.hasNext()) {String key = it.next();sortQueryStringTmp.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(paras.get(key)));}// 去除第一个多余的&符号String sortedQueryString = sortQueryStringTmp.substring(1);StringBuilder stringToSign = new StringBuilder();stringToSign.append("GET").append("&");stringToSign.append(specialUrlEncode("/")).append("&");stringToSign.append(specialUrlEncode(sortedQueryString));String sign = sign(accessSecret + "&", stringToSign.toString());//签名最后也要做特殊URL编码String signature = specialUrlEncode(sign);//生成最后的请求urlString url = aliyunUrl + "?Signature=" + signature + sortQueryStringTmp;String result = HttpUtil.sendGet(url);if (StringUtils.isBlank(result)) {logger.error("阿里云发送短信失败!短信接收人={}, 传入参数={},需要生成URL的参数={}", phone, param , paras);return Base.FAIL;} else {Map<String, String> resultMap = SerializerUtil.deserializeObj(result, Map.class);if (resultMap == null || resultMap.size() < 1) {logger.error("阿里云发送短信失败!短信接收人={}, 传入参数={},需要生成URL的参数={}", phone, param , paras);return Base.FAIL;} else {String code = resultMap.get("Code");if (StringUtils.isNotBlank(code) && StringUtils.equals(code, "OK")){return Base.SUCCESS;} else {logger.error("阿里云发送短信失败!短信接收人={}, 传入参数={},需要生成URL的参数={},返回错误信息={}", phone, param , paras, result);return Base.FAIL;}}}} catch (Exception e) {logger.error("阿里云发送短信程序异常!短信接收人={}, 传入参数={},需要生成URL的参数={}", phone, param , paras, e);return Base.FAIL;}}/*** 根据要求替换字符* @param value* @return* @throws Exception* @author wangyijie* @data 2018年1月10日*/public String specialUrlEncode(String value) throws Exception {return URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");}/*** 生成签名* @param accessSecret* @param stringToSign* @return* @throws Exception* @author wangyijie* @data 2018年1月10日*/public String sign(String accessSecret, String stringToSign) throws Exception {Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");mac.init(new SecretKeySpec(accessSecret.getBytes("UTF-8"), "HmacSHA1"));byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));return new BASE64Encoder().encode(signData);}
}

阿里云短信发送接口直接HTTP请求调用相关推荐

  1. 阿里云短信发送接口调试

    1.注册阿里云账号,并开通云短信服务 开通短信服务时免费的,但是发短信需要从点钱,短信收费可以按发送条数收费 2.充值 3.申请短信签名 4.申请短信模板 5.创建AccessKey,这是很重要,是程 ...

  2. PHP阿里云短信发送文件(带签名)

    <?php namespace app\admin\controller;/*** 阿里云短信发送接口*/ class Alisms {public $accesskeyid = "& ...

  3. PHP 实现 阿里云 短信发送 功能步骤

    1.创建签名 (记住签名名称,后面代码配置中需要),2小时以内会审核通过. 2.创建模板 (记住模板CODE ,后面代码配置中需要) 3. 生成AccessKey ID 和 Access Key Se ...

  4. Java阿里云短信发送工具类

    短信服务API介绍 阿里云短信发送:调用SendSms发送短信_短信服务-阿里云帮助中心 <!--springboot项目阿里云发送短信--> <dependency>< ...

  5. C/C++开发,阿里云短信服务接口的c++实现

    目录 一.阿里云短信服务接口 二.逻辑代码实现 三.编译测试效果 一.阿里云短信服务接口 最近在调用阿里云短信服务接口发现并没有c++的资料,网上查询发现也是零星描述,由于自身项目基础累积了C++的太 ...

  6. PHP 之阿里云短信发送

    一.阿里云短信发送函数封装 function aliyun_sms($mobile,$id,$data){// 引入阿里云短信类require_once $_SERVER['DOCUMENT_ROOT ...

  7. 阿里云短信服务接口返回: 只能向已回复授权信息的手机号发送

    项目场景: 在进入阿里云短信服务时,调用 OpenAPI-发送短信接口 , 返回异常情况及其解决. 问题描述 在进入阿里云短信服务时, 调用测试签名和测试短信模板后, 返回只能向已回复授权信息的手机号 ...

  8. 阿里云短信发送触发天级流量及解决办法

    前言 今天小项目里引入了阿里云短信.调试过程中,突然不发短信了.发现接口返回信息,触发天级流量限制.以下是原因和解决办法. 原因 短信发送有默认的频率限制 限制如下: 短信验证码 :使用同一个签名,对 ...

  9. 最新阿里云短信服务接口类【亲测成功】

    阿里大于 最新的阿里云短信接口,适用于阿里大于搬家以后的情况. 之前一直用阿里大于的短信接口,最近上项目时发现阿里大于悄悄地搬家到了阿里云!阿里云的SDK文件繁多,看得一头雾水!下面代码是最新的可适用 ...

最新文章

  1. 为了智能驾驶,李彦宏要改造城市道路了!
  2. linux mysql详解,Linux 下mysql安装使用详解
  3. Windows-Server下加强系统安全性系列之方案【九】
  4. 那些实用与颜值齐飞的桌面!
  5. kafka-0.10.2.1:Producer生产时无法自动创建Topic
  6. C++之(pair)用法总结
  7. 三十三、Scrapy中的强大媒体管道ImagesPipeline
  8. 【maven3学习之一】window7下maven环境搭建
  9. python 强制结束线程_在python中实现强制关闭线程的示例
  10. 利用代码分别实现jdk动态代理和cglib动态代理_代理模式实现方式及优缺点对比...
  11. 20180914 文件和目录的权限以及属性
  12. 分享一段飞天R502读卡器的JAVA读卡代码
  13. MFC Windows 程序设计[五]之绘制表格Accel
  14. 提高开关电源效率的技巧
  15. 惠普计算机电源怎么设置充电,HP笔记本的三芯电源怎么改二芯实现充电?
  16. OPA2134UA IC AUDIO 2 CIRCUIT 8SOIC
  17. malloc和calloc异同
  18. inverted dropout(反向随机失活)正则化
  19. IPFS未来展望,迎接Web3.0新潮流
  20. 持续集成与持续部署(五)01-TravisCI——使用简介-Travis CI 只支持 Github,提供的是持续集成服务 配置项目的.travis.yml文件

热门文章

  1. AtCoder Beginner Contest 171 D - Replacing
  2. 逻辑函数的描述工具介绍
  3. 知乎网站2010年12月开放,三个月后获得了李开复的天使投资
  4. 万科副总裁毛大庆在建策沙龙上关于楼市走向的发言
  5. 破竹课堂-老A的杠杆术
  6. 根据身份证获取用户的年龄,性别,生日等
  7. html年龄0-120岁正则,正则表达式
  8. php如何配置gii,PHP Framework YII的里的gii设置。
  9. python温度转换代码
  10. this关键字的四种用法