拦截器在Web系统中非常常见,对于某些全局统一的操作,我们可以把它提取到拦截器中实现。总结起来,拦截器大致有以下几种使用场景:
1.权限检查:如登录检测,进入处理程序检测用户是否登录,如果没有,则直接返回登录页面或error错误页面;
2.性能检测:有时系统在某段时间莫名其妙很慢,我们可以通过拦截器在进入处理程序之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间;
3.通用行为;读取cookie得到用户信息并将用户对象放入请求,从而方便后序流程使用,还有提取Locale、Theme信息等,只要是多个处理程序都需要的,即可以使用功能拦截器实现。
下面我来详细介绍如何在SpringBoot项目中搭建拦截器的步骤。
打开IDEA,点击文件,选择新建项目,点击Spring Initializr,然后根据自己的需求设置项目名称,位置以及JDK。这里需要注意,服务器的URL最好设置为阿里云服务器,这样可以使得项目加载地更快。
在自定义的拦截器类中要继承HandlerInterceptor,只有继承了HandlerInterceptor 的类才算是一个拦截器,同时根据需求重写preHandle,postHandle以及afterCompletion方法。
package com.xing.springbootinterceptor.interceptor;
import com.xing.springbootinterceptor.model.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//自定义的拦截器 只有继承了HandlerInterceptor 自定义的类才算是一个拦截器
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//编写拦截的规则
//判断用户是否登录 从session中取值
User user=(User) request.getSession().getAttribute("user");
if(user==null){
//未登录
response.sendRedirect(request.getContextPath()+"/user/error");//重定向
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
编写完自定义的拦截器后,我们还需要将自定义的拦截器注册到Java的配置类中,方便SpringBoot项目启动的时候读取Config配置类。
我们需要创建一个类,实现WebMvcConfigurer接口并在类名上使用 @Configuration注解 表明这是一个配置类,其实就类似于我们在SpringMVC中的XML配置文件,不过现在就用纯Java代码配置而已。
然后在该类中实现 addInterceptors方法,从而把需要拦截的请求以及需要排除的请求注册进去,方便项目启动后的读取。
package com.xing.springbootinterceptor.config;
import com.xing.springbootinterceptor.interceptor.UserInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//表明这是一个配置类 即相当于之前的xml配置文件
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
//这个配置类主要用来添加拦截请求
@Override
public void addInterceptors(InterceptorRegistry registry) {
String[] addPathPatterns={
"/user/**"
};//设置拦截的路径 不设置将会拦截所有的请求
String[] excludePathPatterns={
"/user/out",
"/user/error",
"/user/login"
};//要排除的路径 排除的路径说明不需要用户登录也可以访问
//InterceptorRegistry 拦截器注册类
registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
// WebMvcConfigurer.super.addInterceptors(registry);
}
}
前面展示了不少的url请求,相信没有看到具体的控制器一定有点晕头转向的,这就展示控制器的具体代码,如下所示:
package com.xing.springbootinterceptor.controller;
import com.xing.springbootinterceptor.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController //该注解相当于@Controller+@ResponseBody
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public String login(HttpServletRequest request){
//这里只是模拟登录 一旦输入该请求 则表示登录成功 便我往session中存值
User user = new User();
user.setId(1001);
user.setUsername("张三");
//将用户的信息存放到session中
request.getSession().setAttribute("user",user);
return "login success";
}
//该请求需要用户登录之后才可访问
@RequestMapping("/center")
public String center(){
return "See Center Message";
}
//该请求不登录也可以访问
@RequestMapping("/out")
public String out(){
return "Out See anytime";
}
//如果用户未登录访问了需要登录的请求 便会自动跳转到该路径
@RequestMapping("/error")
public String error(){
return "error";
}
}
通过查看控制器的代码相信大多数小伙伴就能猜测到具体项目演示的结果了,这里就不具体展示运行的效果了。