SpringBoot常用拦截器(HandlerInterceptor,ClientHttpRequestInterceptor,RequestInterceptor)

2022年7月19日08:17:44

SpringBoot常用拦截器(HandlerInterceptor,ClientHttpRequestInterceptor,RequestInterceptor)

上面3种拦截器,都是http拦截器,在处理业务逻辑之前对http请求信息进行处理,比如获取请求头,请求参数,设置请求头,请求参数等等

思路清晰,先说jar包:

HandlerInterceptor—>spring-webmvc项目,org.springframework.web.servlet.HandlerInterceptor

ClientHttpRequestInterceptor—>spring-web项目,org.springframework.http.client.ClientHttpRequestInterceptor

RequestInterceptor—>feign-core项目,feign.RequestInterceptor

一目了然,从项目名称和包路径可以看出,3个拦截器分别属于3个不同的项目,所以他们之前的作用也有区别,在这里我大概讲一下3个拦截器的基本应用和区别:

3个拦截器的共同点,都是对http请求进行拦截,但是http请求的来源不同

  • HandlerInterceptor是最常规的,其拦截的http请求是来自于客户端浏览器之类的,是最常见的http请求拦截器;
  • ClientHttpRequestInterceptor是对RestTemplate的请求进行拦截的,在项目中直接使用restTemplate.getForObject的时候,会对这种请求进行拦截,经常被称为:RestTempalte拦截器或者Ribbon拦截器;
  • RequestInterceptor常被称为是Feign拦截器,由于Feign调用底层实际上还是http调用,因此也是一个http拦截器,在项目中使用Feign调用的时候,可以使用此拦截器;

谈谈HandlerInterceptor

从包路径可以看出,这个是处理客户端http servlet请求的,此项目spring-webmvcspring-mvc项目关闭密切,HandlerInterceptor可以对请求的各个阶段进行拦截,可以说是非常全面了。这个也是常规项目中用的最多的,对http请求进行拦截

publicinterfaceHandlerInterceptor{/**前置处理:在业务处理器处理请求之前被调用*/booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception;/**中置处理:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView ,现在这个很少使用了*/voidpostHandle(
			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;/**后置处理:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等*/voidafterCompletion(
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;

使用示例HandlerInterceptorAdapter实现了HandlerInterceptor接口)

publicclassTestFilterextendsHandlerInterceptorAdapter{privatefinal Logger logger= LoggerFactory.getLogger(TestFilter.class);@OverridepublicbooleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{
		logger.info("request请求地址path[{}] uri[{}]", request.getServletPath(),request.getRequestURI());//request.getHeader(String) 从请求头中获取数据//从请求头中获取用户token(登陆凭证根据业务而定)
		Long userId=getUserId(request.getHeader("H-User-Token"));if(userId!= null&&checkAuth(userId,request.getRequestURI())){returntrue;}//这里的异常是我自定义的异常,系统抛出异常后框架捕获异常然后转为统一的格式返回给前端, 其实这里也可以返回falsethrownewFastRuntimeException(20001,"No access");}private LonggetUserId(String userToken){
	Long userId= null;return userId;}privatebooleancheckAuth(Long userId,String requestURI){returntrue;}@OverridepublicvoidpostHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
					   ModelAndView modelAndView)throws Exception{}@OverridepublicvoidafterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception{}

}

谈谈ClientHttpRequestInterceptor

publicinterfaceClientHttpRequestInterceptor{/**只有这一个方法,在项目中直接使用 restTemplate.getForObject 的时候,会对这种请求进行拦截*/
   ClientHttpResponseintercept(HttpRequest request,byte[] body, ClientHttpRequestExecution execution)throws IOException;

使用示例(SESSIONID可以从RequestContextHolder中拿到)

publicclassRestClientHttpRequestInterceptorimplementsClientHttpRequestInterceptor{@Overridepublic ClientHttpResponseintercept(HttpRequest request,byte[] body, ClientHttpRequestExecution execution)throws IOException{
        HttpHeaders headers= request.getHeaders();
        headers.add("Cookie","SESSIONID=b8dd5bd9-9fb7-48cb-a86b-e079cb554fb8");
        log.info("拦截器已添加header");return execution.execute(request,body);}}

谈谈RequestInterceptor

publicinterfaceRequestInterceptor{/**在项目中使用Feign调用的时候,可以使用此拦截器*/voidapply(RequestTemplate template);}

使用示例

publicclassFeignInterceptorimplementsRequestInterceptor{privatestaticfinal String SESSIONID="SESSIONID";privatestaticfinal String SESSIONID_PREFIX="SESSIONID=";privatestaticfinal String COOKIE="Cookie";@Overridepublicvoidapply(RequestTemplate requestTemplate){
            ServletRequestAttributes servletAttributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest httpServletRequest= servletAttributes.getRequest();
            Cookie[] cookies= httpServletRequest.getCookies();for(Cookie cookie: cookies){if(SESSIONID.equals(cookie.getName())){
                    requestTemplate.header(COOKIE, SESSIONID_PREFIX+cookie.getValue());break;}}}}
  • 作者:岸河
  • 原文链接:https://blog.csdn.net/qq_42145871/article/details/108824056
    更新时间:2022年7月19日08:17:44 ,共 4016 字。