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("/**");
}
}