package sun.flower.diver.base.interceptor; 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; /** * 自定义拦截器 * * @Author YangXuyue * @Date 2018/5/19 13:28 */ public class MyInterceptor implements HandlerInterceptor { /* 不实现HandlerInterceptor的话可以使用继承HandlerInterceptorAdapter */ private static final Logger LOGGER = LoggerFactory.getLogger(MyInterceptor.class); /** * preHandle(……) 方法:该方法的执行时机是,当某个 URL 已经匹配到对应的 Controller 中的某个方法,在这个方法执行之前执行。 * preHandle(……) 方法可以决定是否将请求放行,这是通过返回值来决定的,返回 true 则放行,返回 false 则不会向后执行。 * * @param request request * @param response response * @param handler 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(); LOGGER.info("拦截到了方法:{},在该方法执行之前执行 preHandle(...)", methodName); // 返回true才会继续执行,返回false则取消当前请求 return true; } /** * postHandle(……) 方法:该方法的执行时机是,当某个 URL 已经匹配到对应的 Controller 中的某个方法,执行完了该方法之后触发, * 但是在 DispatcherServlet 视图渲染之前。所以在这个方法中有个 ModelAndView 参数,可以在此做一些修改动作。 * * @param request request * @param response response * @param handler handler * @param modelAndView modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { LOGGER.info("完成请求处理,但是此时还没进行视图渲染,执行 postHandle(...)"); } /** * afterCompletion(……) 方法:该方法是在整个请求处理完成后(包括视图渲染)执行,这个时候可以做一些资源的清理工作, * * @param request request * @param response response * @param handler handler * @param excepion excepion * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception excepion) throws Exception { LOGGER.info("完成请求处理,并渲染相应视图后执行 afterCompletion(...)"); } }
package sun.flower.diver.base.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import sun.flower.diver.base.interceptor.MyInterceptor; /** * Interceptor Config * * @Author YangXuyue * @Date 2018/11/25 22:00 */ @Configuration public class InterceptorConfig implements WebMvcConfigurer { /* 2.0 之前 使用 WebMvcConfigurerAdapter @Deprecated public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {} 2.0 之后 使用 WebMvcConfigurationSupport public class InterceptorConfig extends WebMvcConfigurationSupport {} 使用 WebMvcConfigurationSupport 会导致默认的静态资源被拦截,需要手动将静态资源放开 TODO 没有校验过 2018-11-25 22:03 解决方案: 不继承 WebMvcConfigurationSupport 类,直接实现 WebMvcConfigurer 接口,然后重写 addInterceptors 方法, 将自定义的拦截器添加进去即可 通过实现 WebMvcConfigurer 接口,使 Spring Boot 默认的静态资源不会拦截。 继承 WebMvcConfigurationSupport 类的方式可以用在前后端分离的项目中,后台不需要访问静态资源(就不需要放开静态资源了); 实现 WebMvcConfigurer 接口的方式可以用在非前后端分离的项目中,因为需要读取一些图片、CSS、JS 文件等等。 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()) .addPathPatterns("/**"); } }