Java 手机验证码

发送短信验证码+登陆功能

置顶 2017年12月14日 19:39:55 Elsa晓冰 阅读数:5100 标签: 短信验证码登陆更多

个人分类: ❤【技术点们】…………技术积累

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/binggetong/article/details/78805992

       业务:

       手机端点击发送验证码,调用第三方平台(我们用的是“任信了”平台)的接口,去给手机发短信验证码。

 

  过程:   

                    

 

       代码:

           

 
  1. /**

  2. * 发送短信验证码

  3. * @param json 前台传入电话号码

  4. * @return 返回发送结果向前台

  5. */

  6. @RequestMapping("/getTestCode")

  7. @ResponseBody

  8. public GetTestCodeResult sendTestCode(@RequestParam(value="phone",defaultValue="") String phoneNumber ){

  9.  
  10. GetTestCodeResult result = new GetTestCodeResult();

  11. if(phoneNumber == null || phoneNumber.length()==0 ){

  12. result.setState(Result.ERROR);

  13. result.setMessage("手机号为空");

  14. return result;

  15. }

  16. String code =TestCode.getCode();

  17. if( code== null || code.length()==0){

  18. result.setState(Result.ERROR);

  19. result.setMessage("无效的验证码");

  20. return result;

  21. }

  22.  
  23. try {

  24. SMS.batchsendsm(phoneNumber,code);

  25. } catch (Exception e) {

  26. result.setState(Result.ERROR);

  27. result.setMessage("验证码发送失败");

  28. return result;

  29. }

  30. TestCodeInforVo testCodeInfor = new TestCodeInforVo();

  31. testCodeInfor.setCode(code);

  32. testCodeInfor.setPhone(phoneNumber);

  33. testCodeInfor.setDate(System.currentTimeMillis());

  34. testCodeInforMap.put(phoneNumber,testCodeInfor);

  35. result.setState(Result.SUCCESS);

  36. result.setMessage("验证码发送成功");

  37. result.setData(code); //测试

  38. return result;

  39. }

 

 

        上面这个是发送验证码的方法,其中包括了2个工具类:

 

        No.1 生成5位随机数

        

 
  1. public class TestCode {

  2.  
  3. private final static int codeLength =5;

  4.  
  5. /**

  6. * @see 产生随机验证码

  7. * @return 验证码字符串

  8. */

  9. public static String getCode(){

  10.  
  11. Random rand = new Random();

  12. int a ;

  13. String result ="";

  14. for( int j =0; j<codeLength; j++ ){

  15. a = Math.abs( rand.nextInt()%9 );

  16. result += String.valueOf(a);

  17. }

  18. return result;

  19. }

  20. }

 

 

        No.2 调用第三方发送短信接口

        

 
  1. package com.cn.zhongcai.util.app.util;

  2.  
  3. import java.io.BufferedReader;

  4. import java.io.IOException;

  5. import java.io.InputStreamReader;

  6. import java.io.OutputStreamWriter;

  7. import java.net.HttpURLConnection;

  8. import java.net.URL;

  9. import java.net.URLEncoder;

  10. import java.security.MessageDigest;

  11. import java.security.NoSuchAlgorithmException;

  12.  
  13. public class SMS {

  14.  
  15. //把接口地址和参数赋值,之后调用SMS3方法,参数photo是手机号,code是之前生成的验证码。

  16. public static void batchsendsm(String phone,String code)

  17. {

  18. try{

  19. String userid = URLEncoder.encode("15732622061","UTF-8"); //188

  20.  
  21. String url = "http://apis.renxinl.com:8080/smsgate/varsend.do?";

  22. String para = "user="+userid+"&pwd=9fa41ab9c5352bc29babd621a73d¶ms="+phone+","+code+"&mid=15552";

  23.  
  24. String str="";

  25. str=SMS3(para,url);

  26. System.out.println(str);

  27. }catch (Exception e) {

  28. e.printStackTrace();

  29. }

  30. }

  31.  
  32.  
  33. //postData是上面拼接的参数值,postURL 是接口的地址。我觉得这个方法是能访问到第三方接口的方法。

  34. public static String SMS3(String postData,String postUrl){

  35. try{

  36. URL url = new URL(postUrl);

  37. HttpURLConnection conn = (HttpURLConnection) url.openConnection();

  38. conn.setRequestMethod("POST");

  39.  
  40. conn.setRequestProperty("accept", "*/*");

  41. conn.setRequestProperty("connection", "Keep-Alive");

  42. conn.setRequestProperty("user-agent",

  43. "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

  44. conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

  45.  
  46. conn.setUseCaches(false);

  47. conn.setDoOutput(true);

  48. conn.setDoInput(true);

  49. OutputStreamWriter out= new OutputStreamWriter(conn.getOutputStream(),"UTF-8");

  50. out.write(postData);

  51. out.flush();

  52. out.close();

  53. if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK){

  54. System.out.println("connect failed!");

  55. return "";

  56. }

  57. String line,result = "";

  58. BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));

  59. while((line= in.readLine()) != null){

  60. result += line+"\n";

  61. }

  62. in.close();

  63. return result;

  64. }catch(IOException e){

  65. e.printStackTrace(System.out);

  66. }

  67. return "";

  68. }

  69.  
  70.  
  71.  
  72. }

 

 

        其中:

        1、我从第三方那要了一个demo,从中摘出来自己需要用的代码。

        2、短信接口有固定模板和变量模板, 这里我们用到的是变量模板,因为验证码是个变量。

           

         3、接口文档里给的很清楚:

            

            

 

         4、其中最后一步保存,该手机号的验证码和发送时间,用到了一个Map保存。

           

private final static Map<String, TestCodeInforVo> testCodeInforMap = new HashMap<String,TestCodeInforVo>();

  

 

          发送完验证码之后:

          

testCodeInforMap.put(phoneNumber,testCodeInfor);

         保存到了map里面,到时候找验证码和时间,也从这个map里面找,手机号是key,这个保存着验证码和时间的实体是value。

 

 

         短信验证码就到此告一段落。接下来看登陆的逻辑:

 

 

   登陆的过程:

                                      

 

          登陆代码:

           

 
  1. /**

  2. * 用户登录接口

  3. * @param json 登录参数

  4. * @return 登录成功返回用户信息

  5. */

  6. @RequestMapping("/login")

  7. @ResponseBody

  8. public LoginResult login(@RequestParam(value="testCode",defaultValue="") String testCode,

  9. @RequestParam(value="identity",defaultValue="") String identity,

  10. @RequestParam(value="phone",defaultValue="") String phone, HttpServletRequest request){

  11.  
  12. //String serverPath = request.getScheme() + "://"+ request.getServerName() + ":" +

  13. // request.getServerPort()+request.getContextPath() + "/";

  14.  
  15. LoginResult result = new LoginResult();

  16. if( identity == null || identity.length() == 0 ){

  17. result.setState(Result.ERROR);

  18. result.setMessage("证件号为空");

  19. return result;

  20. }

  21. if(phone== null || phone.length() == 0 ){

  22. result.setState(Result.ERROR);

  23. result.setMessage("手机号为空");

  24. return result;

  25. }

  26. if( testCode == null || testCode.length() == 0 ){

  27. result.setState(Result.ERROR);

  28. result.setMessage("验证码为空");

  29. return result;

  30. }

  31. TestCodeInforVo testCodeInfor = (TestCodeInforVo) testCodeInforMap.get(phone);

  32. if( testCodeInfor == null || testCodeInfor.getCode() == null || testCodeInfor.getCode().length()==0 ){

  33. result.setState(Result.ERROR);

  34. result.setMessage("验证码不存在");

  35. return result;

  36. }

  37.  
  38. if(!testCode.equals(testCodeInfor.getCode())){

  39. result.setState(Result.ERROR);

  40. result.setMessage("验证码错误");

  41. return result;

  42. }

  43. testCodeInforMap.remove(phone);

  44. //验证验证码是否过期

  45. if( System.currentTimeMillis()- testCodeInfor.getDate() > testCodeOutDate ){

  46. result.setState(Result.ERROR);

  47. result.setMessage("验证码已过期");

  48. return result;

  49. }

  50.  
  51. List<UserEntity> users = userService.getUserByPhoneIdentity(phone,identity);

  52. if( users.isEmpty()){

  53. result.setState(Result.ERROR);

  54. result.setMessage("用户不存在");

  55. return result;

  56. }

  57. if( users.size() != 1){

  58. result.setState(Result.ERROR);

  59. result.setMessage("认证用户不唯一");

  60. return result;

  61. }

  62. if( users.get(0).getAccountStatus() != null && users.get(0).getAccountStatus().equals("0")){

  63. result.setState(Result.ERROR);

  64. result.setMessage("该用户被冻结");

  65. return result;

  66. }

  67. UserEntity user = users.get(0);

  68. user.setQrCode(user.getQrCode());

  69. user.setPersonalPhotos(user.getPersonalPhotos());

  70. user.setIdCardAvatarFace(user.getIdCardAvatarFace());

  71. user.setIdCardNationalEmblem(user.getIdCardNationalEmblem());

  72. String siteID="";

  73. //根据user的role去判断该用户所在的站点ID

  74. if (user.getRole()==0) {

  75. //0是管理员

  76. //根据用户的ID去站点表里查询站点的最早添加的哪一个站点Id

  77. siteID=userService.findSiteIDByTimeAdmin(user.getId());

  78. }

  79. if(user.getRole()==2)//2是业主

  80. {

  81. //根据用户的ID去站点表里查询站点的最早添加的哪一个站点Id

  82. siteID=userService.findSiteIDByTimeOwner(user.getId());

  83. }

  84. if (user.getRole()==1) {//1是营业员

  85. //营业员对应的,最早添加的哪一个站点Id

  86. siteID=userService.findSiteIDByTimeOwnerSale(user.getId());

  87. }

  88. user.setSiteID(siteID);

  89. result.setState(Result.SUCCESS);

  90. result.setMessage("登录成功");

  91. AppLoginUser appUser=new AppLoginUser();

  92. HttpSession session=request.getSession();

  93. appUser.setUserID(user.getId());

  94. appUser.setUserName(user.getName());

  95. appUser.setUserNum(user.getUserNumber());

  96. OrgStructure org=orgService.getOrgByAccount(user.getName());

  97. //appUser.setOrgId(org.getOrgId());

  98. session.setAttribute("appLoginUser", appUser);

  99. result.setData(user);

  100. return result;

  101. }

 

 

 

        其中:

        1、判断验证码是否正确:(从刚才那个map里面,根据手机号取值)

          

TestCodeInforVo testCodeInfor =  (TestCodeInforVo) testCodeInforMap.get(phone);

 

 

         从这个实体里面取出验证码和时间。

 

         2、验证码是否过期:

          过期时间:

          

private final static long testCodeOutDate = 5*60*1000;  //验证码过期时间

 

 
  1. //验证验证码是否过期

  2. if( System.currentTimeMillis()- testCodeInfor.getDate() > testCodeOutDate ){

  3. result.setState(Result.ERROR);

  4. result.setMessage("验证码已过期");

  5. return result;

  6. }

 

 

            验证完之后删除他:

         

testCodeInforMap.remove(phone);

 

 

          3、当初想的是存到session里面会怎么写,还没想好,希望路过的大神指导。

 

 

 小结:

      发送验证码和登陆的逻辑之前觉得挺复杂的,当画图总结一遍之后,思路就清楚多了,还是要静下心来多总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值