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

       业务:

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


  过程:   

                    


       代码:

           

/**
	 * 发送短信验证码     
	 * @param json 前台传入电话号码
	 * @return 返回发送结果向前台
	 */
	@RequestMapping("/getTestCode")
	@ResponseBody
	public GetTestCodeResult sendTestCode(@RequestParam(value="phone",defaultValue="") String phoneNumber ){
		
		GetTestCodeResult result = new  GetTestCodeResult();
		if(phoneNumber == null || phoneNumber.length()==0  ){
			result.setState(Result.ERROR);
			result.setMessage("手机号为空");
			return result;
		}
		String code =TestCode.getCode();
		if( code== null || code.length()==0){
			result.setState(Result.ERROR);
			result.setMessage("无效的验证码");
			return result;
		}
		
		try {
			SMS.batchsendsm(phoneNumber,code);
		} catch (Exception e) {
			result.setState(Result.ERROR);
			result.setMessage("验证码发送失败");
			return result;
		}
		TestCodeInforVo testCodeInfor = new TestCodeInforVo();
		testCodeInfor.setCode(code);
		testCodeInfor.setPhone(phoneNumber);
		testCodeInfor.setDate(System.currentTimeMillis());
		testCodeInforMap.put(phoneNumber,testCodeInfor);
		result.setState(Result.SUCCESS);
		result.setMessage("验证码发送成功");
		result.setData(code);  					//测试
		return  result;
	}

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


        No.1 生成5位随机数

        

public class TestCode {

    private final static int codeLength =5;
    
    /**
     * @see 产生随机验证码
     * @return 验证码字符串
     */
	  public static String getCode(){
		  
		 Random rand = new  Random();
		 int  a ;
		 String  result ="";
		 for( int j =0; j<codeLength; j++ ){
			 a = Math.abs( rand.nextInt()%9 );
			 result += String.valueOf(a);
		 }
		 return  result;
	  }
}

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

        

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SMS {

//把接口地址和参数赋值,之后调用SMS3方法,参数photo是手机号,code是之前生成的验证码。
 public static void batchsendsm(String phone,String code)
	{
		try{
			String  userid = URLEncoder.encode("15732622061","UTF-8"); //188			

			String url = "http://apis.renxinl.com:8080/smsgate/varsend.do?";
			String para = "user="+userid+"&pwd=9fa41ab9c5352bc29babd621a73d¶ms="+phone+","+code+"&mid=15552";
			
		  String str="";
		  str=SMS3(para,url);
		  System.out.println(str);
		 }catch (Exception e) {
			 e.printStackTrace();
		}
	}
	
	
//postData是上面拼接的参数值,postURL 是接口的地址。我觉得这个方法是能访问到第三方接口的方法。
	public static String SMS3(String postData,String postUrl){
		try{
			URL url = new URL(postUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");

            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			
			conn.setUseCaches(false);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			OutputStreamWriter out= new OutputStreamWriter(conn.getOutputStream(),"UTF-8");
			out.write(postData);
			out.flush();
			out.close();
			if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK){
				System.out.println("connect failed!");
				return "";
			}
			String line,result = "";
			BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
			while((line= in.readLine()) != null){
				result += line+"\n";
			}
			in.close();
			return result;
		}catch(IOException e){
			e.printStackTrace(System.out);
		}
		return "";
	} 
	
	
	
}

        其中:

        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。


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

 


   登陆的过程:

                                      


          登陆代码:

           

/**
	 * 用户登录接口
	 * @param json 登录参数
	 * @return 登录成功返回用户信息
	 */
	@RequestMapping("/login")
	@ResponseBody
	public LoginResult login(@RequestParam(value="testCode",defaultValue="") String testCode,
			@RequestParam(value="identity",defaultValue="") String identity,
			@RequestParam(value="phone",defaultValue="") String phone, HttpServletRequest request){
		
		//String serverPath =   request.getScheme() + "://"+ request.getServerName() + ":" + 
			//	request.getServerPort()+request.getContextPath() + "/";
		
		LoginResult result = new  LoginResult();
		if( identity == null || identity.length() == 0 ){
			result.setState(Result.ERROR);
			result.setMessage("证件号为空");
			return result;
		}
		if(phone== null || phone.length() == 0 ){
			result.setState(Result.ERROR);
			result.setMessage("手机号为空");
			return result;
		}
		if( testCode == null || testCode.length() == 0 ){
			result.setState(Result.ERROR);
			result.setMessage("验证码为空");
			return result;
		}
		TestCodeInforVo testCodeInfor =  (TestCodeInforVo) testCodeInforMap.get(phone);
		if( testCodeInfor == null || testCodeInfor.getCode() == null || testCodeInfor.getCode().length()==0 ){
			result.setState(Result.ERROR);
			result.setMessage("验证码不存在");
			return result;
		}
		
		if(!testCode.equals(testCodeInfor.getCode())){
			result.setState(Result.ERROR);
			result.setMessage("验证码错误");
			return result;
		}
		testCodeInforMap.remove(phone);
		//验证验证码是否过期
		if( System.currentTimeMillis()- testCodeInfor.getDate() > testCodeOutDate ){
			result.setState(Result.ERROR);
			result.setMessage("验证码已过期");
			return result;
		}  

		List<UserEntity> users = userService.getUserByPhoneIdentity(phone,identity);
		if( users.isEmpty()){
			result.setState(Result.ERROR);
			result.setMessage("用户不存在");
			return result;
		}
		if( users.size() !=  1){
			result.setState(Result.ERROR);
			result.setMessage("认证用户不唯一");
			return result;
		} 
		if(  users.get(0).getAccountStatus() != null &&  users.get(0).getAccountStatus().equals("0")){
			result.setState(Result.ERROR);
			result.setMessage("该用户被冻结");
			return result;
		}
		UserEntity user  = users.get(0);
		user.setQrCode(user.getQrCode());
		user.setPersonalPhotos(user.getPersonalPhotos());
		user.setIdCardAvatarFace(user.getIdCardAvatarFace());
		user.setIdCardNationalEmblem(user.getIdCardNationalEmblem());
		String siteID="";
		//根据user的role去判断该用户所在的站点ID
		if (user.getRole()==0) {
			//0是管理员
			//根据用户的ID去站点表里查询站点的最早添加的哪一个站点Id
			 siteID=userService.findSiteIDByTimeAdmin(user.getId());
		}
		if(user.getRole()==2)//2是业主
		{
			//根据用户的ID去站点表里查询站点的最早添加的哪一个站点Id
			 siteID=userService.findSiteIDByTimeOwner(user.getId());
		}
		if (user.getRole()==1) {//1是营业员
			//营业员对应的,最早添加的哪一个站点Id
			 siteID=userService.findSiteIDByTimeOwnerSale(user.getId());
		}
		user.setSiteID(siteID);
		result.setState(Result.SUCCESS);
		result.setMessage("登录成功");
		AppLoginUser appUser=new AppLoginUser();
		HttpSession session=request.getSession();
		appUser.setUserID(user.getId());
		appUser.setUserName(user.getName());
		appUser.setUserNum(user.getUserNumber());
		OrgStructure org=orgService.getOrgByAccount(user.getName());
		//appUser.setOrgId(org.getOrgId());
		session.setAttribute("appLoginUser", appUser);
		result.setData(user);
		return result;
	}


        其中:

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

          

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

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


         2、验证码是否过期:

          过期时间:

          

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


//验证验证码是否过期
		if( System.currentTimeMillis()- testCodeInfor.getDate() > testCodeOutDate ){
			result.setState(Result.ERROR);
			result.setMessage("验证码已过期");
			return result;
		} 
 

            验证完之后删除他:

         

testCodeInforMap.remove(phone);
 

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



 小结:

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

评论 68
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值