方法一
在Spring Boot中,可以使用拦截器(Interceptor)来实现全局请求拦截。示例:
首先,创建一个拦截器类,实现HandlerInterceptor接口:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;@Component
public class GlobalInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 在请求处理之前进行调用(Controller方法调用之前)// 返回true才会继续向下执行,返回false取消当前请求System.out.println("GlobalInterceptor preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)System.out.println("GlobalInterceptor postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {// 整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要是用于进行资源清理工作)System.out.println("GlobalInterceptor afterCompletion");}}
然后,在配置类中注册拦截器:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate GlobalInterceptor globalInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册拦截器,并设置拦截路径registry.addInterceptor(globalInterceptor).addPathPatterns("/**");}}
在上述示例中,GlobalInterceptor类实现了HandlerInterceptor接口,并重写了preHandle、postHandle和afterCompletion方法。在preHandle方法中,可以进行一些前置处理,如权限验证、日志记录等。在postHandle方法中,可以进行一些后置处理,如修改返回结果、添加额外的响应头等。在afterCompletion方法中,可以进行一些资源清理工作。
在WebConfig配置类中,通过addInterceptors方法将GlobalInterceptor注册为拦截器,并设置拦截路径为"/**"
,表示拦截所有请求。
这样,当有请求进入时,会先经过GlobalInterceptor的preHandle方法,然后进入Controller处理请求,最后再经过GlobalInterceptor的postHandle和afterCompletion方法。
方法二
RequestBodyAdvice
和ResponseBodyAdvice
是Spring框架提供的两个接口,用于在请求处理过程中对请求体和响应体进行处理。
RequestBodyAdvice
用于在请求到达Controller之前对请求体进行处理,可以对请求体进行修改、解析、验证等操作。
ResponseBodyAdvice
用于在Controller方法返回结果之后对响应体进行处理,可以对响应体进行修改、封装、加密等操作。
这两个接口可以同时使用,分别对请求体和响应体进行处理。可以通过实现RequestBodyAdvice
和ResponseBodyAdvice
接口,并注册为Spring的Bean来使用。
例如,可以创建一个实现RequestBodyAdvice
接口的类来处理请求体:
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;import java.io.IOException;
import java.lang.reflect.Type;@ControllerAdvice
public class GlobalRequestBodyAdvice implements RequestBodyAdvice {@Overridepublic boolean supports(MethodParameter methodParameter, Type targetType,Class<? extends HttpMessageConverter<?>> converterType) {// 判断是否支持对该请求进行处理return true;}@Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,Class<? extends HttpMessageConverter<?>> converterType) throws IOException {// 对请求体进行处理,返回处理后的HttpInputMessagereturn inputMessage;}@Overridepublic Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,Class<? extends HttpMessageConverter<?>> converterType) {// 请求体读取完成后的处理,可以对body进行进一步处理return body;}@Overridepublic Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter,Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {// 处理空请求体的情况return body;}
}
同时,可以创建一个实现ResponseBodyAdvice
接口的类来处理响应体:
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;@ControllerAdvice
public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {// 判断是否支持对该响应进行处理return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType,ServerHttpRequest request, ServerHttpResponse response) {// 对响应体进行处理,返回处理后的响应体return body;}
}
在上述示例中,GlobalRequestBodyAdvice
实现了RequestBodyAdvice
接口,用于对请求体进行处理。GlobalResponseBodyAdvice
实现了ResponseBodyAdvice
接口,用于对响应体进行处理。
通过@ControllerAdvice
注解,将这两个类注册为全局的控制器增强,使其生效。
这样,当有请求进入时,会先经过GlobalRequestBodyAdvice
对请求体进行处理,然后进入Controller
处理请求,最后再经过GlobalResponseBodyAdvice
对响应体进行处理。
注意:只有请求参数为@RequestBody,才会执行GlobalRequestBodyAdvice
关系和区别
拦截器(Interceptor)、RequestBodyAdvice和ResponseBodyAdvice可以同时使用。
它们之间的关系和区别如下:
-
拦截器(Interceptor):
- 拦截器是Spring MVC框架提供的一种机制,用于在请求处理的不同阶段进行拦截和处理。
- 拦截器可以在请求处理之前(preHandle)、请求处理之后(postHandle)以及整个请求处理完成之后(afterCompletion)执行一些额外的逻辑。
- 拦截器可以用于实现全局的请求拦截、权限验证、日志记录等功能。
-
RequestBodyAdvice:
- RequestBodyAdvice是Spring框架提供的一个接口,用于在请求处理过程中对请求体进行处理。
- RequestBodyAdvice可以在请求到达Controller之前对请求体进行修改、解析、验证等操作。
- RequestBodyAdvice可以用于实现对请求体的加密解密、数据格式转换、数据校验等功能。
-
ResponseBodyAdvice:
- ResponseBodyAdvice是Spring框架提供的一个接口,用于在Controller方法返回结果之后对响应体进行处理。
- ResponseBodyAdvice可以对响应体进行修改、封装、加密等操作。
- ResponseBodyAdvice可以用于实现对响应体的加密、数据格式转换、数据封装等功能。
这三个功能可以同时使用,各自负责不同的处理逻辑:
- 拦截器可以对请求进行全局拦截和处理,可以用于实现全局的请求拦截、权限验证、日志记录等功能。
- RequestBodyAdvice用于在请求到达Controller之前对请求体进行处理,可以对请求体进行修改、解析、验证等操作。
- ResponseBodyAdvice用于在Controller方法返回结果之后对响应体进行处理,可以对响应体进行修改、封装、加密等操作。
通过同时使用拦截器、RequestBodyAdvice和ResponseBodyAdvice,可以实现更加灵活和全面的请求和响应处理。
拦截器和RequestBodyAdvice在功能和使用场景上有所不同,可以根据具体需求选择使用。
请求参数类型为@RequestBody,执行顺序如下:
GlobalInterceptor preHandle
GlobalRequestBody supports
GlobalRequestBody beforeBodyRead
GlobalRequestBody supports
GlobalRequestBody afterBodyRead
GlobalResponseBody supports
GlobalResponseBody beforeBodyWrite
GlobalInterceptor postHandle
GlobalInterceptor afterCompletion