短信二次接口开发demo

短信二次接口开发demo

利用阿里云平台的短信服务进行二次接口开发,可应用场景,登陆验证码等。本文以完成一次短信验证登陆为主线。新手上路,多多指教。

发送短信的service,此段基本和阿里云的demo一致,也可以参考官方的开发文档demo
http://download.csdn.net/download/qq_33265993/9966476 ali提供的官方sdk及demo)也可以去ali官网下载
本文代码资源
(http://download.csdn.net/download/qq_33265993/9975930)

public class MessageSendServiceImp implements MessageSendService{

    public  SendSmsResponse sendSms(String number,String code) {

        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", BaseConfig.accessKeyId, BaseConfig.accessKeySecret);
        try {
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", BaseConfig.product, BaseConfig.domain);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(number);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName("短信签名");
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode("SMS_80190341");

        request.setTemplateParam("{ \"code\":\""+code+"\"}");

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        request.setOutId("yourOutId");

        //hint 此处可能会抛出异常,注意catch
        SendSmsResponse sendSmsResponse=null;
        try {
            sendSmsResponse = acsClient.getAcsResponse(request);
        } catch (ServerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return sendSmsResponse;
    }
}

上代码中的短信签名和短信模板在阿里云平台这里设置
基本信息配置类


public class BaseConfig {
    //产品名称:云通信短信API产品,开发者无需替换
   public static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
   public static final String domain = "dysmsapi.aliyuncs.com";

    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
   public static final String accessKeyId = "";
   public static final String accessKeySecret = "";
   //此KEY自己设置调用的时候用的key要和这个一直不然签名会失败
   public static final String key="";

}

信息发送的接口类
调用后会返回json,里面有各种信息
{“number”:”xxxxxxxxx”,”code”:”9028”,”nonceStr”:”502e4a16930e414107ee22b6198c578f”,”timeStamp”:”1505210614”,”sign”:”6777FC73D22724442F807F7E6F5FCB5E”,”Code”:”fail”,”message”:”签名错误”}
根据返回的结果判断是否发送成功,成功的时候Code:OK

@Controller
@RequestMapping(value = "/joymeter")
public class MessageSendControl {
@Autowired
private MessageSendService messageSendServiceImp;
     @RequestMapping("/messageSend")
    public void MessageSend(HttpServletRequest request,HttpServletResponse response) {
            String line = null;
            StringBuffer jb = new StringBuffer();
            BufferedReader reader = null;
            try {
                 reader = request.getReader();
               while ((line = reader.readLine()) != null)
                 jb.append(line);

            } catch (Exception e) { 
                    e.printStackTrace();
            }
            System.out.println(jb.toString());
            try {
                reader.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            JSONObject json =  JSONObject.fromObject(jb.toString());
            String number = json.getString("number");
            String code = json.getString("code");
            String sign = json.getString("sign");
            String nonceStr = json.getString("nonceStr");
            String timeStamp = json.getString("timeStamp");
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("number", number);
            map.put("code", code);
            map.put("nonceStr", nonceStr);
            map.put("timeStamp", timeStamp);

            String sign2 = MerchantApiUtil.getSign(map, BaseConfig.key); 

            if(!sign.equals(sign2)) {
                json.put("Code", "fail");
                json.put("message", "签名错误");
            }else {

                //调用发送短信的方法并返回sendSmsresponse
            SendSmsResponse sendSmsresponse = messageSendServiceImp.sendSms(number, code);

            //将返回结果封装到json发送给调用接口者处理
            json.put("Code", sendSmsresponse.getCode());
            json.put("Message", sendSmsresponse.getMessage());
            json.put("RequestId",sendSmsresponse.getRequestId());
            json.put("BizId", sendSmsresponse.getBizId());
            }

            PrintWriter writer=null;
            try {
                writer = response.getWriter();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            writer.print(json.toString());
            writer.flush();

     }
}

上述代码中用到的工具类MerchantApiUtil,是用来生成签名的,具体签名规则参考微信公共号开发的签名生成规则(照着微信的公共号开发是模式写的签名)具体实现没看明白我拷贝过来的。 签名规则:
设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

不愿意看的我会上传资源的
以上就写好了一个短信二次接口,下面有一个简单的测试接口类

public class Test1 {
       private  static String key="000000"; //模拟key值

            public static void main(String[] args) {
                   //请求的URL地址
                    String url="http://localhost:8080/aliduanxin/joymeter/messageSend";
                    JSONObject json = new JSONObject();
                    //发送给的电话号码
                    json.put("number", "xxxxxxxxx");
                    //要发送的验证码值
                    json.put("code", "0000");
                    //随机字符串,随便用什么方式生成
                    json.put("nonceStr", MerchantApiUtil.getNonceStr());
                    json.put("timeStamp", MerchantApiUtil.getTimeStamp());
                    Map<String,Object> map = new HashMap<String,Object>();
                    map.put("number", "xxxxxxx");
                    map.put("code", "0000");
                    //随机字符串
                    map.put("nonceStr", json.getString("nonceStr"));
                    //时间戳
                    map.put("timeStamp", json.getString("timeStamp"));
                    //生成签名

                    String sign = MerchantApiUtil.getSign(map, key);
                    json.put("sign", sign);

                    String outStr = json.toString();
                    json=  HttpUtil.httpRequest(url, "POST",outStr);
                    System.out.println(json);

        }
            }

然后写一个简单的短信验证登陆:
登陆页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登陆</title>
<script type="text/javascript" language="javascript" src="<%=request.getContextPath() %>/js/jquery-3.2.1.js"></script>
</head>
<script type="text/javascript">  
var InterValObj; //timer变量,控制时间  
var count = 10; //间隔函数,1秒执行  
var curCount;//当前剩余秒数  
function reloadCode(){  
      //向后台发送请求生成code并存入session中
      $.post("codeCreate.action", { time : new Date().getTime() } );
      curCount = count;  
      //读秒提示
      $("#btn").attr("disabled", "true");  
      $("#btn").val("请在" + curCount + "秒内输入验证码");  

      //启动定时器
      InterValObj = window.setInterval(SetRemainTime, 1000);
}     
function SetRemainTime() {  
    if (curCount == 0) {                  
        window.clearInterval(InterValObj);// 停止计时器  
        $("#btn").removeAttr("disabled");// 启用按钮  
        $("#btn").val("重新发送验证码");  
//         code = ""; // 清除验证码。如果不清除,过时间后,输入收到的验证码依然有效
        $.post("sessionRemove.action", { time : new Date().getTime(),codeName:'code' } ); 

    }else {  
        curCount--;  
        $("#btn").val("请在" + curCount + "秒内输入验证码");  
    }  
}  

</script>
<body>
<form method='post' action='login.action'>  
    <input type="text" name="code" id="code" value=""/>
    <input type="button" id="btn" value="点击获取验证码" onclick="reloadCode()"/><br>
    <input type="submit" value="Login">  

</form>  
</body>
</html>

效果就是这样只写了验证码其他的不要了,时间可以自己改,测试的时候不愿意等注意这里请求登陆的地址要写
/test/index.action
只写了验证码其他的不要了

后台处理

@Controller
@RequestMapping(value = "/test")
public class Login {
//登陆验证
@RequestMapping("/login.action")
public String login(HttpServletRequest req,HttpServletRequest resp,Map<String,Object> map) {
    String code = req.getParameter("code");
    System.out.println(code);
    System.out.println(req.getSession().getAttribute("code"));
    if(code.equals(req.getSession().getAttribute("code"))) {
        HttpSession session = req.getSession();
        //登陆成功后将code从session中清除
        session.removeAttribute("code");
        System.out.println("登陆成功");
        return "success";
    }
    else {
        System.out.println("登陆失败");
        //返回登陆
        return "redirect:/test/index.action";
    }

}
@RequestMapping("/codeCreate.action")
public void imageCodeCreate(HttpServletRequest req,HttpServletResponse resp) throws IOException {
    //实现短信发送接口的key值,要与configbath中一致
    String key = "123456789";
    String code = (String) ImageCodeCreate.createImageCode().get("code");
    String url = "http://localhost:8080/aliduanxin/joymeter/messageSend";
    JSONObject json = new JSONObject();
    json.put("number", "xxxxxxx");
    json.put("code", code);
    json.put("nonceStr", MerchantApiUtil.getNonceStr());
    json.put("timeStamp", MerchantApiUtil.getTimeStamp());
    Map<String,Object> map = new HashMap<String,Object>();
    map.put("number", "xxxxxxxx");
    map.put("code", code);
    //随机字符串
    map.put("nonceStr", json.getString("nonceStr"));
    //时间戳
    map.put("timeStamp", json.getString("timeStamp"));
    //生成签名

    String sign = MerchantApiUtil.getSign(map, key);
    json.put("sign", sign);
    String outStr = json.toString();
    json=  HttpUtil.httpRequest(url, "POST",outStr);
    System.out.println(json);
//    if(json.getString("Code").equals("OK")) {
        HttpSession session = req.getSession();
        session.setAttribute("code", code);

//      }
}
/**
 * 清楚session中的某个属性
 * @param req
 * @param resp
 */
@RequestMapping("/sessionRemove.action")
public void sessionRemove(HttpServletRequest req,HttpServletResponse resp) {
    String codeName = req.getParameter("codeName");
    req.getSession().removeAttribute(codeName);

}
@RequestMapping("/index.action")
public String index() {
    return "login";
}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值