springboot拦截器(排坑指南)
背景: 对项目中除了登录页面均进行拦截,未登录用户不允许访问其他页面,而是跳转至login.html页面进行登录。
1.创建拦截器:
package com.njust.we.core.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 后台系统身份验证拦截器
*/
@Component
public class AdminLoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
String uri = request.getRequestURI();
String role = (String) request.getSession().getAttribute("loginUser");
if (!uri.contains("/admin")){
return true;
}
if (null == role) { //这里写被拦截后需要执行的操作
request.getSession().setAttribute("errorMsg", "请重新登陆");
//该语句表示当前页面若被拦截即处于未登录状态,则跳转至login进行登录
response.sendRedirect(request.getContextPath() + "/admin/login");
return false;
} else {
request.getSession().removeAttribute("errorMsg");
return true;
}
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
注:
-
@Component注解的使用:表明一个类会作为组件类,并告知Spring要为这个类创建bean,@Component(@Controller、@Service、@Repository)通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中
2.将拦截器添加到配置中
对应于SpringMVC时的配置文件web.xml的相应操作
import com.njust.we.core.interceptor.AdminLoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class MyBlogWebMvcConfigurer implements WebMvcConfigurer {
@Resource
AdminLoginInterceptor adminLoginInterceptor;
public void addInterceptors(InterceptorRegistry registry) {
// 添加一个拦截器
registry.addInterceptor(adminLoginInterceptor)
//添加拦截路径,规定拦截以/admin为前缀的url路径
.addPathPatterns("/projectName/admin/**").addPathPatterns("/admin/**")
.excludePathPatterns("/projectName/admin/login").excludePathPatterns("/admin/login")//忽略路径
.excludePathPatterns("/admin/dist/**").excludePathPatterns("/admin/plugins/**");//忽略login.heml展示所需要的静态资源
}
}
-
问题1:项目本地运行时拦截器有效,但部署到服务器后失效
未添加注解 @Configuration 继承父类选择 implements WebMvcConfigurer 拦截路径可尝试把部署的项目名称放入路径中,同时添加不带项目名称的路径 .addPathPatterns("/projectName/admin/**").addPathPatterns("/admin/**") (因为这个问题试遍了网上各种帖子的办法都解决不了..最后对比本地访问时的路径试出来的办法,无奈又好笑=_=)
-
问题2:访问时出现重定向次数过多
可能是由于没有忽略对登录页面的拦截 .excludePathPatterns("/admin/login")
-
问题3:login.html页面不按预期展示
缺少静态资源,需要排除对该页面所用到的静态资源 的拦截 .excludePathPatterns("/admin/dist/**").excludePathPatterns("/admin/plugins/**")
