目录
学习内容:
基本模块
退出登录功能的实现
/**
* 用户退出
*/
$(".login-out").click(function () {
// 弹出提示框询问用户
layer.confirm('确定退出系统吗?', {icon: 3, title:'系统提示'}, function(index){
// 关闭询问框
layer.close(index);
// 清空cookie信息
$.removeCookie("userIdStr",{domain:"localhost",path:"/crm"});
$.removeCookie("userName",{domain:"localhost",path:"/crm"});
$.removeCookie("trueName",{domain:"localhost",path:"/crm"});
// 跳转到登录页面(父窗口跳转)
window.parent.location.href = ctx + "/index";
});
});
全局异常同意处理
为何要用:
捕获异常过于麻烦,在UserController中只有两行简单的方法却有大堆的catch异常的代码
package com.xxxx.crm;
import com.alibaba.fastjson.JSON;
import com.xxxx.crm.base.ResultInfo;
import com.xxxx.crm.exceptions.AuthException;
import com.xxxx.crm.exceptions.ParamsException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author QQ星
* 全局异常统一处理
* @return
* @Date 2022/2/28 18:48
*/
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
/**
* @param request request请求对象
* @param response response响应对象
* @param handler 方法对象
* @param ex 异常对象
* @return org.springframework.web.servlet.ModelAndView
* @author QQ星
* 异常处理方法
* 方法的返回值:
* 1.返回视图
* 2.返回数据(JSON数据)
* 如何判断方法的返回值
* 通过方法上是否声明@ResponseBody注解
* 如果声明了,则表示返回数据
* 如果未声明,则表示返回数据
* @Date 2022/2/28 18:48
*/
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
/**
* 设置默认异常处理(返回视图)
*/
ModelAndView modelAndView = new ModelAndView("error");
//设置异常信息
modelAndView.addObject("code", 500);
modelAndView.addObject("msg", "异常异常,请重试...");
//判断HandlerMethod
if (handler instanceof HandlerMethod) {
//类型转换
HandlerMethod handlerMethod = (HandlerMethod) handler;
//获取方法上声明的@RepsonseBody注解对象
ResponseBody responseBody = handlerMethod.getMethod().getDeclaredAnnotation(ResponseBody.class);
//判断ResponseBody对象是否为空 (如果对象为空,则表示返回的是视图;如果不为空,则表示返回的是数据)
if (responseBody == null) {
/**
* 方法返回视图
*/
if (ex instanceof ParamsException) {
ParamsException p = (ParamsException) ex;
//设置异常信息
modelAndView.addObject("code", p.getCode());
modelAndView.addObject("msg", p.getMsg());
}
return modelAndView;
} else {
/**
* 方法返回数据
*/
//设置默认的异常处理
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(500);
resultInfo.setMsg("异常异常,请重试!");
//判断异常类型是否是自定义异常
if (ex instanceof ParamsException) {
ParamsException p = (ParamsException) ex;
resultInfo.setCode(p.getCode());
resultInfo.setMsg(p.getMsg());
}
//设置响应类型及编码格式(响应JSON格式的数据)
response.setContentType("application/json;charset=UTF-8");
//得到字符串输出流
PrintWriter out = null;
try {
// 得到输出流
out = response.getWriter();
// 将需要返回的对象转换成JOSN格式的字符
String json = JSON.toJSONString(resultInfo);
// 输出数据
out.write(json);
} catch (IOException e) {
e.printStackTrace();
} finally {
//如果对象不为空,则关闭
if (out != null) ;
out.close();
}
}
return null;
}
return modelAndView;
}
}
非法请求拦截
思路:
判断用户是否是登录状态
获取Cookie对象,解析用户ID的值
如果用户ID不为空,且在数据空中存在对应的用户记录,表示请求合法
否则,请求不合法,进行拦截,重定向到登录界面
新思想:根据不同页面用户能否访问来进行拦截,让用户转到指定登录界面
/**
* 非法访问拦截
* 继承HandlerInstantiator
*
*/
public class NoLoginInterceptor extends HandlerInterceptorAdapter{
//注入UserMapper
@Resource
private UserMapper userMapper;
/**
* @author QQ星
*
* 拦截用户是否是登录状态
* 在目标方法(目标资源)执行前,执行的方法
*
* 方法返回布尔类型:
* 如果返回true,表示目标方法可以被执行
* 如果返回false,则表是目标方法执行
* 如何判断用户是否是登录状态:
* 1.判断Cookie中是否1存在用户信息(获取用户ID)
* 2.数据库中是否存在指定用户ID的值
*
* 如果用户是登录状态,则允许目标方法执行:如果用户是非登录状态,则抛出未登录异常(在全局异常中做判断,如果是未登录异常,则跳转到登录页面)
*
* @param request
* @param response
* @param handler
* @return boolean
* @Date 2022/3/1 17:22
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取cookie中的用户ID
Integer userId = LoginUserUtil.releaseUserIdFromCookie(request);
//
if (null==userId||userMapper.selectByPrimaryKey(userId)==null){
//抛出未登录异常
throw new NoLoginException();
}
return true;
}
}
在GlobalExceptionResolver加入非法拦截请求
/**
* 非法请求拦截
* 判断是否抛出未登录
* 如果抛出该异常,则要求用户登录,重定向跳转到登录界面
*/
if (ex instanceof NoLoginException) {
//重新定向到登录
ModelAndView modelAndView =new ModelAndView("redirect:/index");
return modelAndView;
}
设置需要放行的一些页面
@Configuration//配置类
public class MvcConfig extends WebMvcConfigurerAdapter {
@Bean //将方法的返回值交给IOC维护
public NoLoginInterceptor noLoginInterceptor(){
return new NoLoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//需要一个实现了拦截器功能的实例对象,这里使用的是noLoginInterceptor
registry.addInterceptor(noLoginInterceptor())
//设置需要拦截1的资源
.addPathPatterns("/**") //默认拦截所有的资源
//设置不需要拦截的资源
.excludePathPatterns("/css/**","/images/**","/js/**","/lib/**","/index","/user/login");
}
}
记住我功能
记住我功能核心在于当用户上次登录时如果点击了记住我,下次在重新打开游览器的时候可以不用选择登录,此时可以借助拦截器+cookie来实现,当用户登录时,如果用户点击了记住我功能,默认设置cookie存储时间为七天即可
// 判断用户是否选择记住密码(判断复选框是否被选中,
如果选中,则设置cookie对象7天生效)
if ($("#rememberMe").prop("checked")) {
// 选中,则设置cookie对象7天生效
// 将用户信息设置到cookie中
$.cookie("userIdStr",result.result.userIdStr, {expires:7});
$.cookie("userName",result.result.userName, {expires:7});
$.cookie("trueName",result.result.trueName, {expires:7});
}
学习时间:
2022-2-28 15:40-18:43、19:43-22.14
2022-3-1 9:54-11:43、16:00-18:03、20:00-23:30