一、SpringMvc拦截器
为什么引入拦截器
首先设想这样一个场景,我们想要实现用户修改密码的功能,那么,应该怎么实现呢?
第一步,思考要传入的参数都有什么,因为是修改密码,所以肯定要传入原密码以及新密码,这两个是必传的。至于用户id,用户名这些,为了防止有人恶意修改等,就不需要再传了,这些参数我们就可以通过用户登录时产生的唯一token进行获取。
第二步,要想修改密码,就要保证传入的token是正确的,并且是在有效时间内。如果传入的token不正确,或者未进行传入,那么我们就要进行拦截,前端看不到任何信息,因为接口被拦截。只有正确传入token(这里不一定,只是我这个情景是这样,要看具体接口),这个请求才是有效的,这时输入正确的原密码以及设置好新密码。才可以修改成功。
拦截器的定义
SpringMVC中的interceptor拦截器,它主要的作用是拦截指定的用户请求,并进行相应的预处理与后处理。其拦截的时间点在“处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前。”当然处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。
拦截器执行原理
拦截器的使用步骤:
1.定义类实现HandlerInterceptor接口
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Resource
private IUserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){
String auth = request.getHeader("auth");
if (StrUtil.isBlank(auth)){
return false;
}
ResultUtil authentication = userService.authentication(auth);
if (authentication.getCode().equals("403")){
return false;
}
return true;
}
2.在springmvc配置文件中,声明拦截器, 让框架知道拦截器的存在。
@Configuration
public class SpringMvcController implements WebMvcConfigurer {
@Resource
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/user/check/**") //这里是要拦截的
.excludePathPatterns("/user/open/**"); //这里是不需要拦截的
//一般我们写接口时,可以用check和open进行区分
}
}
拦截器的执行时间:
1)在请求处理之前, 也就是controller类中的方法执行之前先被拦截。
2)在控制器方法执行之后也会执行拦截器。
3)在请求处理完成后也会执行拦截器。
一般拦截器被用在:
日志记录:记录请求信息的日志
权限检查:如登录检查
性能检测:检测方法的执行时间
二、统一异常拦截
@RestControllerAdvice
@Slf4j
public class ExceptionConfig {
@ResponseBody
@ExceptionHandler(Exception.class)
public ResultUtil exceptionHandler(Exception e){
log.error("系统执行异常",e);
return ResultUtil.success(e.getMessage());
}
}
注意一定要加上@RestControllerAdvice这个注解
这里的ResultUtil是自己简单封装的,仅供参考
@Data
public class ResultUtil {
private String code;
private String message;
private Object data;
public static ResultUtil success(Object data){
ResultUtil resultUtil = new ResultUtil();
resultUtil.setCode("200");
resultUtil.setMessage("请求成功");
resultUtil.setData(data);
return resultUtil;
}
}
三、非法sql拦截
我们可以使用mybatisplus写好的,在config包下加入这个类
@RestControllerAdvice
@Slf4j
public class ExceptionConfig {
@ResponseBody
@ExceptionHandler(Exception.class)
public ResultUtil exceptionHandler(Exception e){
log.error("系统执行异常",e);
return ResultUtil.success(e.getMessage());
}
}