目录
1. ResponseBodyAdvice
2. supports方法
3. beforeBodyWrite方法
4. 实践
1. ResponseBodyAdvice
Spring MVC的ResponseBodyAdvice是Spring 4.1版本中引入的一个接口,它允许在Controller控制器中@ResponseBody修饰的方法或ResponseEntity执行之后,对自定义响应中的内容进行处理。
具体来说,当Controller方法返回一个值时,该值会作为入参传递给ResponseBodyAdvice的beforeBodyWrite()方法。在beforeBodyWrite()方法中,你可以对返回值进行一些定制操作,例如对返回值进行一层封装,然后再将其写入到response中。
ResponseBodyAdvice只支持@ResponseBody注解的Controller方法,因此如果Controller方法中没有@ResponseBody注解,ResponseBodyAdvice无法对其返回值进行处理。
使用ResponseBodyAdvice可以实现以下两个主要功能:
统一处理http接口返回值结构:由于不同的http接口返回值结构可能各异,因此需要一种方式来统一处理这些返回值。通过使用ResponseBodyAdvice,可以在返回值写入response之前对其进行封装,将不同的返回值结构统一为一种结构,方便后续处理。
对http接口返回值进行加密处理:为了保护数据的安全性,有时候需要对http接口返回值进行加密处理。使用ResponseBodyAdvice可以在返回值写入response之前对其进行加密,从而避免将加密逻辑入侵到每个接口代码中,简化了加密处理的过程。
使用ResponseBodyAdvice的方法有两种:
在RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver中注册实现类:可以直接将实现类注册到RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver中,让Spring自动检测并使用。
使用@ControllerAdvice注解:可以将实现类用@ControllerAdvice注解进行标记,让Spring自动检测并使用。同时,被@ControllerAdvice注解标记的类可以起到集中处理的作用,可以对多种情况进行统一处理。
总的来说,ResponseBodyAdvice是Spring MVC中一个非常有用的接口,它可以对Controller控制器中@ResponseBody修饰的方法或ResponseEntity执行之后自定义响应中的内容进行处理,从而实现统一处理http接口返回值结构和加密处理等功能。
有两个比较重要的方法进行讲解。
2. supports方法
Spring MVC的ResponseBodyAdvice接口中的supports方法主要是用于判断是否符合处理条件。这个方法的返回值是一个布尔值,当返回值为true时,会调用beforeBodyWrite方法对返回值进行处理,否则不进行处理。
具体来说,当一个Controller方法返回一个值时,该值会作为参数传递给supports方法。在supports方法中,你可以编写自己的逻辑来判断是否需要对返回值进行处理。如果返回true,则将返回值传递给beforeBodyWrite方法,在beforeBodyWrite方法中对返回值进行处理后,再将其写入response中。
一般来说,supports方法的实现会比较简单,只需要根据特定的条件判断是否需要对返回值进行处理即可。例如,如果需要对返回值进行加密处理,可以在supports方法中判断请求的url是否符合加密处理的条件,如果符合则返回true,否则返回false。
需要注意的是,supports方法只判断是否需要对返回值进行处理,并不会对Controller方法的返回值类型进行限制。因此,如果Controller方法返回一个自定义类型,需要自行实现supports方法来支持对该类型的处理。
3. beforeBodyWrite方法
Spring MVC的ResponseBodyAdvice接口中的beforeBodyWrite方法是在Controller控制器中@ResponseBody修饰的方法或ResponseEntity执行之后,对自定义响应中的内容进行处理的具体实现方法。
具体来说,当Controller方法返回一个值时,该值会作为参数传递给supports方法进行判断是否需要处理。如果返回true,则将返回值作为参数传递给beforeBodyWrite方法。在beforeBodyWrite方法中,你可以编写自己的逻辑来对返回值进行处理,例如对返回值进行一层封装、加密处理等,然后将处理后的结果写入response中返回给客户端。
一般来说,beforeBodyWrite方法的实现会比较复杂,需要详细的逻辑来对返回值进行处理。例如,如果需要对返回值进行加密处理,可以在beforeBodyWrite方法中获取加密秘钥,然后对返回值进行加密处理,最后将加密后的结果写入response中返回给客户端。
需要注意的是,beforeBodyWrite方法的参数中包括了Request对象和Response对象,可以从中获取到请求和响应的相关信息。因此,在实现beforeBodyWrite方法时,可以根据需要对请求和响应进行相应的处理。
总的来说,Spring MVC的ResponseBodyAdvice接口中的beforeBodyWrite方法是实现自定义响应处理的核心方法,通过它可以将返回值进行一层封装、加密处理等操作,最终将处理后的结果写入response中返回给客户端。
4. 实践
自定义注解@ResultResponse,作为supports的判断条件,是否用来处理。
新建类ResponseBodyAdvice实现ResponseBodyAdvice,重写supports和beforeBodyWrite方法。
新建BaseController,类上添加注解@ApiResultResponse。
// 1
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResultResponse {
boolean enable() default true;
}
// 2
@RestControllerAdvice
@RequiredArgsConstructor
public class ResponseBodyAdvice implements ResponseBodyAdvice {
/*
1. MethodParameter是Spring MVC中的一个类,代表着一个方法参数,包括方法参数的注解、参数类型等信息。
在supports方法中,可以通过MethodParameter对象获取当前处理方法的注解、返回值类型等信息,从而对请求进行相应的处理。
2. Class extends HttpMessageConverter>>是HttpMessageConverter接口的子类类型,代表着用于处理HTTP消息的转换器类型。
在supports方法中,可以通过Class对象获取用于处理HTTP消息的转换器类型,从而根据不同的转换器类型对请求和响应进行相应的处理。
*/
@Override
public boolean supports(MethodParameter returnType,
Class extends HttpMessageConverter>> converterType) {
//根据相应逻辑进行判断是否需要处理
}
/* Object代表着Controller方法的返回值,即需要进行处理的对象。
在beforeBodyWrite方法中,可以通过该对象获取返回值的具体内容,并对其进行相应的处理。
MethodParameter是Spring MVC中的一个类,代表着一个方法参数,包括方法参数的注解、参数类型等信息。
在beforeBodyWrite方法中,可以通过MethodParameter对象获取当前处理方法的注解、返回值类型等信息,从而对请求进行相应的处理。
MediaType是Spring MVC中的一个类,代表着HTTP消息的媒体类型,例如application/json、text/html等。在beforeBodyWrite方法中,
可以通过MediaType对象获取当前处理请求的媒体类型,从而根据不同的媒体类型对请求和响应进行相应的处理。
Class extends HttpMessageConverter>>是HttpMessageConverter接口的子类类型,代表着用于处理HTTP消息的转换器类型。
在beforeBodyWrite方法中,可以通过Class对象获取用于处理HTTP消息的转换器类型,从而根据不同的转换器类型对请求和响应进行相应的处理。
ServerHttpRequest是Spring MVC中的一个接口,代表着当前处理的HTTP请求。
在beforeBodyWrite方法中,可以通过ServerHttpRequest对象获取当前请求的相关信息,例如请求头、请求参数等,从而对请求进行相应的处理。
ServerHttpResponse是Spring MVC中的一个接口,代表着当前处理的HTTP响应。
在beforeBodyWrite方法中,可以通过ServerHttpResponse对象获取当前响应的相关信息,例如响应头、响应状态码等,从而对响应进行相应的处理。
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class
extends HttpMessageConverter>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
//进行实际处理
}
}
// 3
@ApiResultResponse
public class BaseController {
}
实际开发中Controller继承BaseController就可用了。