赞
踩
一:拦截器
拦截全局请求HandlerInterceptor
public interface HandlerInterceptor { /** * 预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller * 返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应; */ boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; /** * 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。 */ void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; /** * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中 */ void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
用途:
拦截非法请求,日志记录等。
用法:
1.直接实现HandlerInterceptor接口,实现三个方法
/** * HandlerInterceptor 拦截请求,过滤掉非法请求 */ public class CheckTokenGetHandler implements HandlerInterceptor { @Autowired private CheckTokenRequest checkTokenRequest; @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { String token = httpServletRequest.getParameter("cookieid"); //根据token,校验token是否存在合法 if (checkTokenRequest.tokenIsExist(token)){ return true; }else { //返回false之前,设置response相应前台 checkTokenRequest.returnJson(httpServletResponse); return false; } //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 { } }
2.继承HandlerInterceptorAdapter适配器
有时候我们的业务需求只需要实现三个回调函数之间的一个,所以不需要实现所有的方法,Spring提供了一个HandlerInterceptor的适配器HandlerInterceptorAdapter,继承这个类,重写需要用到的回调方法即可。
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { public HandlerInterceptorAdapter() { } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } //这个方法是AsyncHandlerInterceptor独有的方法 public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { } }
拦截器HandlerInterceptor的装载
写一个配置类,继承WebMvcConfigurerAdapter,重写addInterceptors添加拦截器(可同时加载多个拦截器)
/** * web MVC配置类,加载拦截器 */ @Configuration public class DeveloperWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter { @Bean public CheckTokenGetHandler getCheckTokenGetHandler(){ return new CheckTokenGetHandler(); } public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getCheckTokenGetHandler()).addPathPatterns("/**"); } }
有一点需要注意!spring在启动时,@Configuration注解的类生产出让Spring IoC容器管理的Bean实例的工厂。@Bean注解的方法产生一个对象,注册到容器中,这里联合使用@Bean和@Configuration注解使得在实体类中使用的@Autowired注解能够顺利将实体类注入,如果不提前声明Bean,拦截器将在SpringContext(加载Bean)之前注册,从而导致拦截器中的@Autowired注解的变量将为null。顺便提一下@PostConstruct这个注解在@Autowired注解修饰的变量或者方法之后执行,可以用来做一些初始化方法的加载。
二:请求的过滤及处理
RequestBodyAdvice
仅支持post请求,数据以body的形式发送
实现RequestBodyAdvice类或者继承RequestBodyAdviceAdapter(RequestBodyAdvice适配器)
在实现类上加注解@ControllerAdvice
import java.io.IOException; import java.lang.reflect.Type; import org.springframework.core.MethodParameter; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; public interface RequestBodyAdvice { //这里是一个前置拦截匹配操作,其实就是告诉你满足为true的才会执行下面的beforeBodyRead方法,这里可以定义自己业务相关的拦截匹配 boolean supports(MethodParameter var1, Type var2, Class<? extends HttpMessageConverter<?>> var3); //当请求体为空时调用(可拦截body为空的请求) Object handleEmptyBody(Object var1, HttpInputMessage var2, MethodParameter var3, Type var4, Class<? extends HttpMessageConverter<?>> var5); //在请求体未读取(转换)时调用(可对数据进行处理,解密数据,过滤非法数据,重新序列化等) HttpInputMessage beforeBodyRead(HttpInputMessage var1, MethodParameter var2, Type var3, Class<? extends HttpMessageConverter<?>> var4) throws IOException; //在请求体完成读取后调用(可针对读取后的对象做转换,此处不做处理) Object afterBodyRead(Object var1, HttpInputMessage var2, MethodParameter var3, Type var4, Class<? extends HttpMessageConverter<?>> var5); }
ResponseBodyAdvice
ResponseBodyAdvice 的用途在于对返回内容做拦截处理:
public interface ResponseBodyAdvice<T> {
// 返回true,启动拦截,false,不启动拦截
boolean supports(MethodParameter var1, Class<? extends HttpMessageConverter<?>> var2);
//在返回数据之前启动拦截,比如做数据的加密处理等
T beforeBodyWrite(T var1, MethodParameter var2, MediaType var3, Class<? extends HttpMessageConverter<?>> var4, ServerHttpRequest var5, ServerHttpResponse var6);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。