1. 主要技术
SpringBoot+Mybatis+spring+mysql+layui
2. 目前的项目图
3. 目前的实现功能
(1)登录功能
登录的逻辑主要是下判断是否存在该用户,如果存在该用户就比较密码是否正确,如果正确登录成功。
主要是三层:
controller:接受请求、返回结果
接受前端的参数
调用service层的登录方法
返回给前端
@PostMapping("login") @ResponseBody public ResultInfo userLogin(String userName,String userPwd){ ResultInfo resultInfo=new ResultInfo(); UserModel userModel=userService.userLogin(userName,userPwd); resultInfo.setResult(userModel); return resultInfo; }service层:业务逻辑层(非空判断、条件判断)
判空操作
调用dao层通过用户名查询对象
@Resource private UserMapper userMapper; /*** * login成功后返回一个userModel * 1.检查用户、密码是否为空 * 2.通过用户名查询user * 3.检查密码是否正确 * 4.生成一个usermodel返回给controller * @param userName * @param userPwd * @return */ @Override public UserModel userLogin(String userName,String userPwd){ checkLoginParams(userName,userPwd); User user=userMapper.queryByUserByName(userName); AssertUtil.isTrue(user==null,"用户姓名不存在"); checkUserPwd(userPwd,user.getUserPassword()); return buildUserInfo(user); } private UserModel buildUserInfo(User user) { UserModel userModel=new UserModel(); userModel.setUserIdStr(UserIDBase64.encoderUserID(user.getId())); userModel.setUserName(user.getUserName()); userModel.setTrueName(user.getTrueName()); return userModel; } private void checkUserPwd(String userPwd, String userPassword) { userPwd= Md5Util.encode(userPwd); AssertUtil.isTrue(!userPwd.equals(userPassword),"用户密码不正确"); } /*** * 检查用户名、密码是否为空 * @param userName * @param userPwd */ private void checkLoginParams(String userName, String userPwd) { AssertUtil.isTrue(StringUtils.isBlank(userName),"用户姓名不能为空"); AssertUtil.isTrue(StringUtils.isBlank(userPwd),"用户密码不能为空"); }其中AssertUtil为工具类:
public class AssertUtil { public static void isTrue(Boolean flag,String msg){ if(flag){ throw new ParamsException(msg); } } }dao层:与数据层相关
(2)修改密码
思路:
controller层:
接受前端传到的三个参数(旧密码、新密码、确认的新密码)
利用request获取到cookie中的主键ID
调用service层的修改密码方法
返回给前端参数
@ResponseBody @PostMapping("updatePassword") public ResultInfo updatePassword(HttpServletRequest request,String oldPassword, String newPassword, String repeatPassword){ ResultInfo resultInfo=new ResultInfo(); System.out.println(oldPassword); try{ Integer userId= LoginUserUtil.releaseUserIdFromCookie(request); userService.updatePassword(userId,oldPassword,newPassword,repeatPassword); }catch (ParamsException p){ resultInfo.setCode(p.getCode()); resultInfo.setMsg(p.getMsg()); p.printStackTrace(); }catch (Exception e){ resultInfo.setCode(500); resultInfo.setMsg("登录失败"); e.printStackTrace(); } return resultInfo; } @RequestMapping("toPasswordPage") public String toPasswordPage(){ return "user/password"; }service层:
接受controller的四个参数
通过id查询用户user
参数校验:
user是否为空
旧密码是否为空,旧密码是否错误
新密码是否为空,新密码是否与旧密码相同
确认新密码是否为空,确认信密码是否与新密码相同
对新密码进行加密
调用dao层进行密码更新
执行更新判断受影响行数,判断是否更新成功
@Override @Transactional(propagation = Propagation.REQUIRED) public void updatePassword(Integer userId,String oldPwd,String newPwd,String repeatPwd ){ User user=userMapper.selectByPrimaryKey(userId); AssertUtil.isTrue(user==null,"待更新记录不存在"); System.out.println(oldPwd); checkPasswordParams(user,oldPwd,newPwd,repeatPwd); user.setUserPassword(Md5Util.encode(newPwd)); userMapper.updateByPrimaryKeySelective(user); AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user)<1,"修改密码失败"); } private void checkPasswordParams(User user,String oldPwd, String newPwd, String repeatPwd) { AssertUtil.isTrue(StringUtils.isBlank(oldPwd),"旧密码不能为空"); AssertUtil.isTrue(user.getUserPassword().equals(Md5Util.encode(oldPwd)),"原始密码不正确"); AssertUtil.isTrue(StringUtils.isBlank(newPwd),"新密码不能为空"); AssertUtil.isTrue(newPwd.equals(oldPwd),"新密码不能与旧密码相同"); AssertUtil.isTrue(StringUtils.isBlank(repeatPwd),"确认新密码不能为空"); AssertUtil.isTrue(!repeatPwd.equals(newPwd),"确认新密码与新密码不一致"); }dao层:
数据库的update操作
(3)记住我、退出功能
记住我和退出主要都是通过cookies进行实现,主要在前端js就可以实现
// 如果点击记住我 设置cookie 过期时间7天 if($("input[type='checkbox']").is(':checked')){ // 写入cookie 7天 $.cookie("userId",result.userIdStr, { expires: 7 }); $.cookie("userName",result.userName, { expires: 7 }); $.cookie("trueName",result.trueName, { expires: 7 }); }
$(".login-out").click(function () { layer.confirm('是否登出当前用户?', {icon: 3, title:'提示'}, function(index){ $.removeCookie("userId",{path:"/"}) $.removeCookie("userName",{path:"/"}) $.removeCookie("trueName",{path:"/"}) window.parent.location.href = ctx + "/index"; layer.close(index); });
(4)拦截器
当用户未登录的时候不能直接访问到主页面main
拦截器:
/** * 非法访问拦截 */ public class NoLoginInterceptor extends HandlerInterceptorAdapter { @Resource private UserServiceImpl userService; /** * 判断用户是否是登录状态 * 获取Cookie对象,解析用户ID的值 * 如果用户ID不为空,且在数据库中存在对应的用户记录,表示请求合法 * 否则,请求不合法,进行拦截,重定向到登录页面 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取Cookie中的用户ID Integer userId = LoginUserUtil.releaseUserIdFromCookie(request); // 判断用户ID是否不为空,且数据库中存在对应的用户记录 if (null == userId || null == userService.selectByPrimaryKey(userId)) { // 抛出未登录异常 throw new UnLoginException(); } return true; } }配置拦截器:
@Configuration public class MvcConfig extends WebMvcConfigurerAdapter { @Bean public NoLoginInterceptor noLoginInterceptor() { return new NoLoginInterceptor(); } /** * 添加拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { // 需要一个实现HandlerInterceptor接口的拦截器实例,这里使用的是 NoLoginInterceptor registry.addInterceptor(noLoginInterceptor()) // 用于设置拦截器的过滤路径规则 .addPathPatterns("/**") // 用于设置不需要拦截的过滤规则 .excludePathPatterns("/index","/user/login","/css/**","/images/**","/js/**","/lib/**"); } }
4. 异常
(1)参数异常
/** * 自定义参数异常 */ public class ParamsException extends RuntimeException { private Integer code=300; private String msg="参数异常!"; public ParamsException() { super("参数异常!"); } public ParamsException(String msg) { super(msg); this.msg = msg; } public ParamsException(Integer code) { super("参数异常!"); this.code = code; } public ParamsException(Integer code, String msg) { super(msg); this.code = code; this.msg = msg; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(