SpringBoot配置拦截器
大司空° 人气:0如何配置拦截器
step1: 自定义拦截器
/** * 自定义拦截器 */ public class MyInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class); /** * 在请求匹配controller之前执行,返回true才行进行下一步 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return false; } /** * 已经执行完controller了,但是还没有进入视图渲染 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * 视图也渲染完了,此时我可以做一些清理工作了 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
step2:配置拦截器
@Configuration public class MyInterceptorConfig extends WebMvcConfigurationSupport { @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 拦截所有内容:/** 拦截部分内容:/admin/** super.addInterceptors(registry); } }
拦截器设置容易出现的问题
静态资源被拦截
MyInterceptorConfig 继承 WebMvcConfigurationSupport类时,会导致resources/static下的静态资源也被拦截,如果我们不想静态资源被拦截,可以尝试以下两种方法。
/** * 在MyInterceptorConfig中重写addResourceHandlers方法,重新指定静态资源 * 推荐在前后端分离时使用,后台不需要访问静态资源 * * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations( "classpath:/static/"); super.addResourceHandlers(registry); }
/** * 将MyInterceptorConfig类由继承WebMvcConfigurationSupport改为实现WebMvcConfigurer * 推荐在非前后端分离时使用,后台需要访问静态资源 * */ @Configuration public class MyInterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 拦截所有内容:/** 拦截部分内容:/admin/** } }
如何取消拦截操作
step1:自定义注解
/** * 自定义注解用来指定某个方法不用拦截 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UnInterception { }
step2:修改拦截器MyInterceptor中的preHandle方法
/** * 在请求匹配controller之前执行 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { UnInterception unInterception = method.getAnnotation(UnInterception.class); if(null != unInterception) { logger.info("不需要拦截,可以执行"); return true; } // 返回true才会执行方法,返回false不会执行 return false; }
step3:在不需要拦截的controller上加上UnInterception注解
@Controller @RequestMapping("/interceptor") public class InterceptorController { @UnInterception @RequestMapping("/test") public String test() { return "hello"; } }
实例-登录验证
用拦截器实现一个登录验证功能
step1:自定义拦截器
import com.kimmel.course13.annotation.UnInterception; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; /** * 自定义拦截器 */ public class MyInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class); /** * 在请求匹配controller之前执行 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); String methodName = method.getName(); // 判断用户有没有登录,一般登录之后的用户都有一个对应的token UnInterception unInterception = method.getAnnotation(UnInterception.class); String token = request.getParameter("token"); if (null == token || "".equals(token)) { logger.info("用户未登录,没有权限执行{}请登录", methodName); return false; } // 返回true才会执行方法,返回false不会执行 return true; } /** * 已经执行完controller了,但是还没有进入视图渲染 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); String methodName = method.getName(); logger.info("已经执行完{}了,但是还没有进入视图渲染", methodName); } /** * 视图也渲染完了,此时我可以做一些清理工作了 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { logger.info("视图也渲染完了,此时我可以做一些清理工作了"); } }
step2:配置拦截器
import com.kimmel.course13.Interceptor.MyInterceptor; 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.WebMvcConfigurationSupport; @Configuration public class MyInterceptorConfig extends WebMvcConfigurationSupport { @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 拦截所有内容:/** 拦截部分内容:/admin/** super.addInterceptors(registry); } /** * 发现如果继承了WebMvcConfigurationSupport,则在yml中配置的相关内容会失效。 需要重新指定静态资源 * * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations( "classpath:/static/"); registry.addResourceHandler("swagger-ui.html").addResourceLocations( "classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations( "classpath:/META-INF/resources/webjars/"); super.addResourceHandlers(registry); } }
step3:自定义测试controller
@Controller @RequestMapping("/interceptor") public class InterceptorController { @RequestMapping("/test") public String test() { return "hello"; } }
step4:测试
进入浏览器,输入http://localhost:8080/interceptor/test
结果:无法进入,日志:用户未登录,没有权限执行 test 请登录
进入浏览器,输入http://localhost:8080/interceptor/test?token=1
结果:成功进入hello.html
加载全部内容