零、 login.html / SessionInterceptor
<html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="assets/global/plugins/bootstrap/css/bootstrap.min.css" type="text/css"/> <link rel="stylesheet" href="assets/global/css/components.css" type="text/css"/> <link rel="stylesheet" href="assets/admin/pages/css/login.css" type="text/css"/> <script rel="stylesheet" src="assets/global/plugins/jquery-1.11.0.min.js" type="text/javascript"></script> <link rel="stylesheet" href="selectMeiHua.css"> </head> <body class="login" background="edge_bj_1.jpg"> <div class="content"> <h3 class="form-title">用户登录</h3> <div class="form-group"> <label class="control-label">手机号</label> <div> <input type="text" class="form-control" placeholder="手机号" name="telphone" id="telphone"> </div> </div> <div class="form-group"> <label class="control-label">密码</label> <div> <input type="password" class="form-control" placeholder="密码" name="password" id="password"> </div> </div> <div> <button class="btn green" id="login" type="submit"> 登录 </button> <button class="btn green" id="toRegister"> 注册 </button> </div> </div> </body> <script> jQuery(document).ready(function () { //跳转到注册页面 $("#toRegister").on("click", function () { window.location.href="getotp.html"; }) //绑定otp的click事件用于向后端发送手机验证码的请求 $("#login").on("click", function () { var tel = $("#telphone").val(); var password = $("#password").val(); if (tel == null || tel == '') { alert("用户手机号不能为空"); return false; } if (password == null || password == '') { alert("用户密码不能为空"); return false; } $.ajax({ type: "POST", contentType: "application/x-www-form-urlencoded", url: "http://localhost:8080/user/login", data: { "telphone": $("#telphone").val(), "encrptPassword": $("#password").val(), }, dataType: "json", xhrFields: { withCredentials: true }, crossDomain: true, success: function (result) { if (result.status == "success") { alert(result.data) } else { alert("请求失败 原因为:" + result.data.errMsg) } }, error: function (data) { alert("请求失败 原因为:" + data.responseText) } }); }) }) </script> </html>
1 package com.miaoshaProject.login_config; 2 3 import com.miaoshaProject.dataobject.UserDO; 4 import com.miaoshaProject.service.model.UserModel; 5 import org.springframework.stereotype.Component; 6 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 7 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 import java.io.PrintWriter; 11 12 /** 13 * @Description 登录超时拦截器 14 * @Author rongtao 15 * @Data 2019/4/24 13:37 16 * https://www.codeleading.com/article/4517856247/ 17 */ 18 @Component 19 public class SessionInterceptor extends HandlerInterceptorAdapter { 20 //拦截action 21 @Override 22 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 23 throws Exception { 24 UserModel user = (UserModel) request.getSession().getAttribute("LOGIN_USER"); 25 System.out.println(user); 26 //session中User过期 27 if(user == null){ 28 String uri = request.getRequestURI(); 29 System.out.println(uri); 30 //ajax请求响应头会有,x-requested-with 31 if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with") 32 .equalsIgnoreCase("XMLHttpRequest")) { 33 //在响应头设置session状态 34 response.setHeader("sessionstatus", "timeout"); 35 response.setHeader("url", uri.substring(0, uri.indexOf("/", 1))); 36 } else { 37 PrintWriter out = response.getWriter(); 38 StringBuilder sb = new StringBuilder(); 39 sb.append("<script type=\"text/javascript\" charset=\"UTF-8\">"); 40 sb.append("alert(\"登录超时,请重新登录\");"); 41 sb.append("window.top.location.href=\""); 42 sb.append("/login.html"); 43 sb.append("\";</script>"); 44 out.print(sb.toString()); 45 out.close(); 46 } 47 //返回false不再调用其他的拦截器和处理器 48 return false; 49 } 50 return true; 51 } 52 }
一、项目层级
二、ValidatorImpl
1 package com.miaoshaProject.validator; 2 3 import org.springframework.beans.factory.InitializingBean; 4 import org.springframework.stereotype.Component; 5 6 import javax.validation.ConstraintViolation; 7 import javax.validation.Validation; 8 import javax.validation.Validator; 9 import java.util.Set; 10 11 /** 12 * @Author wangshuo 13 * @Date 2022/4/16, 14:14 14 * Please add a comment 15 */ 16 @Component//声明bean 17 public class ValidatorImpl implements InitializingBean { 18 19 private Validator validator; 20 21 //实现校验方法并返回校验结果 22 public ValidationResult validator(Object bean){ 23 24 final ValidationResult result = new ValidationResult(); 25 final Set<ConstraintViolation<Object>> set = validator.validate(bean); 26 if (set.size() > 0){ 27 result.setHasErrors(true); 28 //Lambda表达式 29 set.forEach(ConstraintViolation->{ 30 String errMsg = ConstraintViolation.getMessage(); 31 String propertyName = ConstraintViolation.getPropertyPath().toString(); 32 result.getErrorMap().put(propertyName,errMsg); 33 }); 34 } 35 return result; 36 } 37 38 @Override 39 public void afterPropertiesSet() throws Exception { 40 //将hibernate validator通过工厂的初始化方式使其实例化 41 this.validator = Validation.buildDefaultValidatorFactory().getValidator(); 42 } 43 }
三、ValidationResult
1 package com.miaoshaProject.validator; 2 3 import org.apache.commons.lang3.StringUtils; 4 5 import java.util.HashMap; 6 import java.util.Map; 7 8 /** 9 * @Author wangshuo 10 * @Date 2022/4/16, 14:06 11 * Please add a comment 12 */ 13 public class ValidationResult { 14 15 //校验结果 16 private boolean hasErrors = false; 17 18 //存放错误信息的map 19 private Map<String,String> errorMap = new HashMap<>(); 20 21 //实现通用的通过格式化字符串获取错误结果的方法 22 public String getErrMsg(){ 23 24 //map --》 array --》 String 25 String join = StringUtils.join(errorMap.values().toArray(), ","); 26 return join; 27 } 28 29 public boolean isHasErrors() { 30 return hasErrors; 31 } 32 33 public void setHasErrors(boolean hasErrors) { 34 this.hasErrors = hasErrors; 35 } 36 37 public Map<String, String> getErrorMap() { 38 return errorMap; 39 } 40 41 public void setErrorMap(Map<String, String> errorMap) { 42 this.errorMap = errorMap; 43 } 44 }
四、UserModel
1 package com.miaoshaProject.service.model; 2 3 import javax.validation.constraints.Max; 4 import javax.validation.constraints.Min; 5 import javax.validation.constraints.NotBlank; 6 import javax.validation.constraints.NotNull; 7 import java.io.Serializable; 8 9 /** 10 * @Author wangshuo 11 * @Date 2022/4/12, 19:46 12 * 要实现 Serializable接口,不然没办法放到session中 13 */ 14 public class UserModel implements Serializable { 15 16 private Integer id; 17 @NotBlank(message = "用户名不能为空") 18 private String name; 19 @NotNull(message = "性别填写有误") 20 private Integer gender; 21 @NotNull(message = "年龄填写有误") 22 @Min(value = 0, message = "年龄必须大于零") 23 @Max(value = 150, message = "年龄不能大于150") 24 private Integer age; 25 @NotBlank(message = "手机号不能为空") 26 private String telpphone; 27 private String registerMode; 28 private String thiredPartyId; 29 @NotBlank(message = "密码不能为空") 30 private String encrptPassword; 31 32 public Integer getId() { 33 return id; 34 } 35 36 public void setId(Integer id) { 37 this.id = id; 38 } 39 40 public String getName() { 41 return name; 42 } 43 44 public void setName(String name) { 45 this.name = name; 46 } 47 48 public Integer getGender() { 49 return gender; 50 } 51 52 public void setGender(Integer gender) { 53 this.gender = gender; 54 } 55 56 public Integer getAge() { 57 return age; 58 } 59 60 public void setAge(Integer age) { 61 this.age = age; 62 } 63 64 public String getTelpphone() { 65 return telpphone; 66 } 67 68 public void setTelpphone(String telpphone) { 69 this.telpphone = telpphone; 70 } 71 72 public String getRegisterMode() { 73 return registerMode; 74 } 75 76 public void setRegisterMode(String registerMode) { 77 this.registerMode = registerMode; 78 } 79 80 public String getThiredPartyId() { 81 return thiredPartyId; 82 } 83 84 public void setThiredPartyId(String thiredPartyId) { 85 this.thiredPartyId = thiredPartyId; 86 } 87 88 public String getEncrptPassword() { 89 return encrptPassword; 90 } 91 92 public void setEncrptPassword(String encrptPassword) { 93 this.encrptPassword = encrptPassword; 94 } 95 }
五、UserController
1 //用户注册接口 2 @RequestMapping(value = "/login", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED}) 3 @ResponseBody 4 public CommonReturnType userRegister(@RequestParam(name = "telphone") String telphone, 5 @RequestParam(name = "encrptPassword") String encrptPassword) throws BusinessException, NoSuchAlgorithmException { 6 7 //入参校验 8 if (StringUtils.isEmpty(telphone) || StringUtils.isEmpty(encrptPassword)){ 9 throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR); 10 } 11 //用户登录服务 12 UserModel userModel = uesrService.validateLogin(telphone, this.encodeByMD5(encrptPassword)); 13 //服务层没throw Exception,用户登录成功,将凭证加入session内 14 this.httpServletRequest.getSession().setAttribute("LOGIN_USER",userModel); 15 return CommonReturnType.create("登录成功"); 16 }
六、UserServiceImpl
1 @Override 2 @Transactional//保证事务唯一性 3 public void register(UserModel userModel) throws BusinessException { 4 5 /*if (userModel == null) 6 throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR); 7 if (StringUtils.isEmpty(userModel.getName()) || userModel.getGender() == null || 8 StringUtils.isEmpty(userModel.getTelpphone()) || userModel.getAge() == null || 9 StringUtils.isEmpty(userModel.getRegisterMode())) { 10 11 throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR); 12 }*/ 13 //更新校验规则 14 ValidationResult result = this.validator.validator(userModel); 15 if (result.isHasErrors()) 16 throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,result.getErrMsg()); 17 UserDO userDO = convertFromModelObject(userModel); 18 //使用selective 19 //处理用户重复注册异常 20 try { 21 userDOMapper.insertSelective(userDO); 22 } catch (DuplicateKeyException e) { 23 throw new BusinessException(EnumBusinessError.REGISTER_REPEAT); 24 } 25 26 //把刚刚新增成功的userId赋值给UserPasswordDO用于密码表的新增 27 userModel.setId(userDO.getId()); 28 UserPasswordDO userPasswordDO = convertPasswordFromModelObject(userModel); 29 userPasswordDOMapper.insertSelective(userPasswordDO); 30 } 31 32 @Override 33 public UserModel validateLogin(String telphone, String encrptPassword) throws BusinessException { 34 35 UserDO userDO = userDOMapper.selectByTelphone(telphone); 36 if (userDO == null) 37 throw new BusinessException(EnumBusinessError.LOGIN_ERROR); 38 UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUserId(userDO.getId()); 39 UserModel userModel = convertFromDataObject(userDO, userPasswordDO); 40 //比对用户信息内加密的密码是否与传输来的密码相匹配 41 if (!StringUtils.equals(encrptPassword, userModel.getEncrptPassword())) { 42 43 throw new BusinessException(EnumBusinessError.LOGIN_ERROR); 44 } 45 //登录成功,返回model 46 return userModel; 47 }
七、UserDOMapper
<select id="selectByTelphone" resultMap="BaseResultMap"> <!-- WARNING - @mbg.generated This element is automatically generated by MyBatis Generator, do not modify. This element was generated on Thu Apr 14 10:32:50 CST 2022. --> select <include refid="Base_Column_List" /> from user_info where telpphone = #{telphone,jdbcType=VARCHAR} </select>
八、EnumBusinessError
1 package com.miaoshaProject.error; 2 3 /** 4 * @Author wangshuo 5 * @Date 2022/4/14, 8:43 6 * 自定义error 7 */ 8 public enum EnumBusinessError implements CommonError{ 9 //10001 参数不合法 10 PARAMETER_VALIDATION_ERROR(10001,"参数不合法"), 11 //20000未知错误 12 UNKNOWN_ERROR(20000,"未知错误"), 13 //以30000开头的错误码代表用户信息错误 14 USER_NOT_EXISTS(30001,"用户不存在"), 15 REGISTER_OTP_ERROR(30002,"验证码错误"), 16 REGISTER_REPEAT(30003,"该手机号已注册账户,请勿重复注册"), 17 LOGIN_ERROR(30004,"用户手机号或密码不正确") 18 ; 19 20 private EnumBusinessError(Integer code,String msg){ 21 22 this.errorCode = code; 23 this.errorMsg = msg; 24 } 25 26 private int errorCode; 27 private String errorMsg; 28 29 @Override 30 public int getErrorCode() { 31 return this.errorCode; 32 } 33 34 @Override 35 public String getErrorMsg() { 36 return this.errorMsg; 37 } 38 39 //定制化的方法改动错误信息 40 @Override 41 public CommonError setErrorMsg(String msg) { 42 this.errorMsg = msg; 43 return this; 44 } 45 }
本文来自博客园,作者:荣慕平,转载请注明原文链接:https://www.cnblogs.com/rongmuping/articles/16153228.html