java对接短信平台
2018-07-09 13:27:07来源:博客园 阅读 ()
短信验证码目前是比较主流验证身份的一种方式,下面分享下我对接的几种短信平台
阿里云短信:https://api.alidayu.com/docs/api.htm?spm=a3142.7395905.4.7.W5QHoB&apiId=26039
信信客短信:www.xinxinke.com(这个平台老板我熟,需要商业合作可以留言)
下面直接上代码
/** * 短信发送工厂类 * * @author zhangyi * @version 2.0 * @time 2018年7月3日 下午3:31:57 */ public class SmsFactory {
// snsSwitch 可以作为一个短信开关来使用,后面扩展其他平台时,可以在里面继续加,也可以通过反射的方式代替switch public static SmsCore createSmsCore(int smsSwitch) { SmsCore smsCore = null; switch (smsSwitch) { case 1: smsCore = new AliYunSmsCore(); break; case 2: smsCore = new XxkSmsCore(); break; } return smsCore; } }
/** * 短信类 * * @author zhangyi * @version 2.0 * @time 2018年5月30日 下午2:02:01 */ public abstract class SmsCore { public abstract ResultUtil send(SmsParam smsParam) throws Exception; }
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; public class AliYunSmsCore extends SmsCore { private static Log logger = LogFactory.getLog(AliYunSmsCore.class); // 产品名称:云通信短信API产品,开发者无需替换 static final String product = "Dysmsapi"; // 产品域名,开发者无需替换 static final String domain = "dysmsapi.aliyuncs.com"; public ResultUtil send(SmsParam smsParam) throws Exception { // 可自助调整超时时间 System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "10000"); // 初始化acsClient,暂不支持region化 IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", smsParam.getAppId(), smsParam.getAppKey()); DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); IAcsClient acsClient = new DefaultAcsClient(profile); // 组装请求对象-具体描述见控制台-文档部分内容 SendSmsRequest request = new SendSmsRequest(); // 必填:必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式 request.setPhoneNumbers(smsParam.getMobile()); // 必填:短信签名-可在短信控制台中找到 request.setSignName(smsParam.getSignName()); // 必填:短信模板-可在短信控制台中找到 request.setTemplateCode(smsParam.getSmsTemplateCode()); // 可选:模板中的变量替换JSON串 request.setTemplateParam(smsParam.getContent()); logger.info("阿里云短信发送参数,手机号码:" + smsParam.getMobile() + ",验证码:" + smsParam.getContent() + ",短信签名:" + smsParam.getSignName() + ",短信模板:" + smsParam.getSmsTemplateCode()); // hint 此处可能会抛出异常,注意catch SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); logger.info("阿里云短信发送响应response,code:" + sendSmsResponse.getCode() + ", msg:" + sendSmsResponse.getMessage()); if ("OK".equalsIgnoreCase(sendSmsResponse.getCode())) { return ResultUtil.ok().set("code", "200").set("msg", "发送成功!"); } else { return ResultUtil.fail().set("code", "400").set("msg", sendSmsResponse.getMessage()); } } }
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.security.MessageDigest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import net.sf.json.JSONObject; /** * 信信客短信工具类 */ public class XxkSmsCore extends SmsCore { private static Log logger = LogFactory.getLog(XxkSmsCore.class); // 转码 public String encode(String input) throws Exception { return URLEncoder.encode(input, "UTF-8"); } // 计算 MD5 值 public static String md5(String input) throws Exception { byte[] digest = MessageDigest.getInstance("MD5").digest(input.getBytes("UTF-8")); StringBuffer sb = new StringBuffer(); for (int i = 0; i < digest.length; i++) { sb.append(String.format("%02x", Integer.valueOf(digest[i] & 0xFF))); } return sb.toString(); } // 发起 POST 请求 public String post(String url, String data) throws Exception { // 打开连接 HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); conn.setUseCaches(false); conn.connect(); // 输出参数 DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); dos.writeBytes(data); dos.flush(); dos.close(); // 读取响应 BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String line = br.readLine(); br.close(); // 关闭连接 conn.disconnect(); return line; } /** * 短信发送接口 * * @param smsTemplateCode * 短信模板编号 * @param smsParam * 短信模板变量 {\"code\":\"" + Math.random() + "\"} * @param recNum * 接收号码 * @param recNum * 短信签名 * @throws Exception */ public ResultUtil send(SmsParam smsParam) throws Exception { ResultUtil rs = ResultUtil.fail(); // 参数 String url = "http://www.xinxinke.com/api/send"; String sign = md5(smsParam.getAppId() + smsParam.getAppKey() + smsParam.getMobile()); // 拼接 StringBuffer data = new StringBuffer(); data.append("").append("dev_id").append("=").append(encode(smsParam.getAppId())); data.append("&").append("sign").append("=").append(encode(sign)); data.append("&").append("sms_template_code").append("=").append(encode(smsParam.getSmsTemplateCode())); data.append("&").append("sms_param").append("=").append(encode(smsParam.getContent())); data.append("&").append("rec_num").append("=").append(encode(smsParam.getMobile())); data.append("&").append("sms_sign").append("=").append(encode(smsParam.getSignName())); logger.info("信信客短信发送参数,手机号码:" + smsParam.getMobile() + ",验证码:" + smsParam.getContent() + ",短信签名:" + smsParam.getSignName() + ",短信模板:" + smsParam.getSmsTemplateCode()); String response = post(url, data.toString()); logger.info("信信客短信发送响应,response:" + response); JSONObject jsonObject = JSONObject.fromObject(response); String code = jsonObject.getString("code"); if ("25010".equals(code)) { return ResultUtil.ok().set("code", "200").set("msg", "发送成功!"); } return rs.set("msg", jsonObject.getString("data")); } }
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;
// 使用了loombok插件,如果不使用则自己写set get方法即可 @Data @NoArgsConstructor @AllArgsConstructor public class SmsParam { private String appId; private String appKey; private String signName; private String smsTemplateCode; private String content; private String mobile; public SmsParam(String appId, String appKey, String signName, String smsTemplateCode) { this.appId = appId; this.appKey = appKey; this.signName = signName; this.smsTemplateCode = smsTemplateCode; } }
其中 ResultUtil是返回工具类,如果不用,可以自行替换
import java.util.HashMap; import java.util.Map; public class ResultUtil extends HashMap { private static final String STATE = "state"; private static final String STATE_OK = "ok"; private static final String STATE_FAIL = "fail"; public static ResultUtil create(Object key, Object value) { return new ResultUtil().set(key, value); } public static ResultUtil create() { return new ResultUtil(); } public static ResultUtil ok() { return new ResultUtil().setOk(); } public static ResultUtil ok(Object key, Object value) { return ok().set(key, value); } public static ResultUtil fail() { return new ResultUtil().setFail(); } public static ResultUtil fail(Object key, Object value) { return fail().set(key, value); } public ResultUtil setOk() { super.put("state", "ok"); return this; } public ResultUtil setFail() { super.put("state", "fail"); return this; } public boolean isOk() { Object state = get("state"); if ("ok".equals(state)) { return true; } if ("fail".equals(state)) { return false; } throw new IllegalStateException("调用 isOk() 之前,必须先调用 ok()、fail() 或者 setOk()、setFail() 方法"); } public boolean isFail() { Object state = get("state"); if ("fail".equals(state)) { return true; } if ("ok".equals(state)) { return false; } throw new IllegalStateException("调用 isFail() 之前,必须先调用 ok()、fail() 或者 setOk()、setFail() 方法"); } public ResultUtil set(Object key, Object value) { super.put(key, value); return this; } public ResultUtil set(Map map) { super.putAll(map); return this; } public ResultUtil set(ResultUtil ret) { super.putAll(ret); return this; } public ResultUtil delete(Object key) { super.remove(key); return this; } public <T> T getAs(Object key) { return (T) get(key); } public String getStr(Object key) { Object s = get(key); return s != null ? s.toString() : null; } public Integer getInt(Object key) { Number n = (Number) get(key); return n != null ? Integer.valueOf(n.intValue()) : null; } public Long getLong(Object key) { Number n = (Number) get(key); return n != null ? Long.valueOf(n.longValue()) : null; } public Number getNumber(Object key) { return (Number) get(key); } public Boolean getBoolean(Object key) { return (Boolean) get(key); } public boolean notNull(Object key) { return get(key) != null; } public boolean isNull(Object key) { return get(key) == null; } public boolean isTrue(Object key) { Object value = get(key); return ((value instanceof Boolean)) && (((Boolean) value).booleanValue() == true); } public boolean isFalse(Object key) { Object value = get(key); return ((value instanceof Boolean)) && (!((Boolean) value).booleanValue()); } @Override public boolean equals(Object ret) { return ((ret instanceof ResultUtil)) && (super.equals(ret)); } @Override public String toString() { return "ResultUtil [toString()=" + super.toString() + "]"; } }
实际调用
String content = String.valueOf(new Random().nextDouble()).substring(3, 9); SmsParam smsParam = initSmsParam(templateType, smsSwitch); smsParam.setMobile(mobile); smsParam.setContent("{\"code\": \"" + content + "\"}"); // 工厂类生产具体短信发送类 SmsCore smsCore = SmsFactory.createSmsCore(smsSwitch); // 短信发送 resultUtil = smsCore.send(smsParam);
只用配置smsSwitch(短信服务选型:0=测试短信888888,1=阿里云短信,2=信信客短信),顺便贴出我实际用的配置
public enum SmsCoreTypeEnum { TEST(0, "test"), AlI(1, "ali"), XXK(2, "xxk"); public int type; public String desc; public int getType() { return type; } public String getDesc() { return desc; } private SmsCoreTypeEnum(int type, String desc) { this.type = type; this.desc = desc; } public static void main(String[] args) { System.out.println(AlI.getType() + "--" + AlI.getDesc()); System.out.println(SmsCoreTypeEnum.AlI.getType()); } }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash