拦截器在实际项目开发中很重要,下面以登录拦截器为例,要用户登录才能访问系统中的请求
1、自定义一个拦截器 LoginHandlerInterceptor,实现 HandlerInterceptor接口,重写里面的 preHandle方法:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class LoginHandlerInterceptor implements HandlerInterceptor{
/**
* 重新调用目标请求前的拦截方法
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//判断session中是否有用户信息
Object loginUser = request.getSession().getAttribute("loginUser");
if(loginUser != null) {
//已经登录,不进行拦截,放行
return true;
}
//未登录,进行拦截,跳转到登录页面,并且在 request 中携带错误信息
request.setAttribute("msg", "无权限,请先登录!");
//通过服务器转发到登录页面,这里不是使用重定向,因为要通过request携带错误信息,index.html 就是之前自定义的视图,用于跳转到登录页面的请求
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
}
}
2、自定义拦截器之后,要将拦截器加入到web容器中,可以通过自定以的 webMvc配置类,来向springboot注入一个 WebMvcConfigurer 组件,在组件中将拦截器加入进去
/**
* 声明这个类是一个配置类
* @author asong
*
*/
@Configuration
public class MySpringMvcConfigurer {
/**
* 向 spring容器中注入一个组件,组件的类型是 WebMvcConfigurer,组件的id是 webMvcConfigurer
* 可以通过这个自定义的webMvc组件,向容器中添加webmvc控制,比如添加视图控制,添加拦截器等等
* @return
*/
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
/**
* 添加一个自定义的视图控制,用于访问 springboot 项目的默认首页
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("main/login");
registry.addViewController("/index.html").setViewName("main/login");
registry.addViewController("/main.html").setViewName("main/index");
}
/**
* 将自定义的拦截器,通过webmvc组件添加到容器中,
* 注意,这里添加拦截器也和 web项目增加过滤器一样,存在先后顺序之分
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//将自定义的登录拦截器添加到容器中
registry.addInterceptor(new LoginHandlerInterceptor())
//拦截所有的请求 /**
.addPathPatterns("/**")
//排除不需要拦截的请求,这里是:去登录页面的请求、登录表单提交请求
.excludePathPatterns("/", "/index.html", "/login")
//springboot2 版本之后,需要在拦截器中排除静态资源路径,否则静态资源会被拦截
.excludePathPatterns("/css/**", "/js/**", "/img/**");
}
};
}
}
3、登录请求的Controller
/**
* 登录请求
* @param username
* @param password
* @param request
* @return
*/
@PostMapping("/login")
public String login(String username, String password, HttpServletRequest request, Model model) {
if(!StringUtils.isEmpty(username) && "123".equals(password)) {
//用户名不为空,且密码是 123 则表示登录成功
//登录成功,用户信息存入session
request.getSession().setAttribute("loginUser", username);
//防止表单重复提交,这里登录成功之后,重定向到主页,但是这里重定向表示的还是一个请求,一个url,所以需要自定义个一个视图,来表示 /main.html 请求跳转到 主页
return "redirect:/main.html";
}
//登录失败,返回登录页面
model.addAttribute("msg", "用户名或密码错误!");
return "main/login";
}