Detailed Explanation of the Use of ResponseBodyAdvice in Spring

  • 2021-12-04 18:57:09
  • OfStack

Directory 1 Introduction to ResponseBodyAdvice 2 Use of ResponseBodyAdvice 1 Prepare an SpringBoot Project Environment 3 Add 1 Return Wrapper Class 4 Add Control Class 5 Interface Test

ResponseBodyAdvice Can be found in annotations @ResponseBody Operate the return value before processing it into the corresponding format. Implement this interface to complete the corresponding operation. It can be used to encapsulate or encrypt response data

Introduction to 1 ResponseBodyAdvice

The ResponseBodyAdvice interface is similar to the RequestBodyAdvice interface recorded before. RequestBodyAdvice is intercepted before requesting Controller to do corresponding processing operations, while ResponseBodyAdvice is returned to Controller {@code @ResponseBody}or a {@code ResponseEntity} After that, {@code HttpMessageConverter} Intercept before type conversion, perform corresponding processing operations, and then return the results to the client.

Source code for ResponseBodyAdvice:


/**    The processing order of data is downward 
 * Allows customizing the response after the execution of an {@code @ResponseBody}
 * or a {@code ResponseEntity} controller method but before the body is written
 * with an {@code HttpMessageConverter}.
 *
 * <p>Implementations may be registered directly with
 * {@code RequestMappingHandlerAdapter} and {@code ExceptionHandlerExceptionResolver}
 * or more likely annotated with {@code @ControllerAdvice} in which case they
 * will be auto-detected by both.
 *
 * @author Rossen Stoyanchev
 * @since 4.1
 * @param <T> the body type
 */
public interface ResponseBodyAdvice<T> {

	/**
	 * Whether this component supports the given controller method return type
	 * and the selected {@code HttpMessageConverter} type.
	 * @param returnType the return type    The type returned by the method 
	 * @param converterType the selected converter type    Parameter type replacement 
	 * @return {@code true} if {@link #beforeBodyWrite} should be invoked;
	 * {@code false} otherwise
	 *  Return  true  Then the following  beforeBodyWrite Method is called ,  Otherwise, the following method is not called 
	 */
	boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);

	/**
	 * Invoked after an {@code HttpMessageConverter} is selected and just before
	 * its write method is invoked.
	 * @param body the body to be written
	 * @param returnType the return type of the controller method
	 * @param selectedContentType the content type selected through content negotiation
	 * @param selectedConverterType the converter type selected to write to the response
	 * @param request the current request
	 * @param response the current response
	 * @return the body that was passed in or a modified (possibly new) instance
	 */
	@Nullable
	T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
			Class<? extends HttpMessageConverter<?>> selectedConverterType,
			ServerHttpRequest request, ServerHttpResponse response);

}

Description:

supports method: Judge whether to execute beforeBodyWrite method, true is executed, false is not executed. Through this method, you can choose which classes or which methods response should be processed, and others should not be processed. beforeBodyWrite method: Carry out specific operation treatment on response method

{@ code @ ResponseBody} returns the body of the response, such as the List collection

{@ code ResponseEntity} Returns a response entity object, such as an User object

2 Use of ResponseBodyAdvice

1 Prepare an SpringBoot project environment

2 Add 1 response interception class


@ControllerAdvice
public class BaseResponseBodyAdvice implements ResponseBodyAdvice<Object> {


    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
            MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request,
            ServerHttpResponse response) {

        //  Encounter feign Requests such as interfaces ,  It should not be repackaged , Should return directly 
        //  Solutions to the above problems :  Can be found in feign In the interceptor , To feign Add to the request header 1 Identification fields ,  Means yes feign Request 
        //  Intercepted here feign Identification field ,  It is released directly   Return body.

        System.out.println(" Response interception succeeded ");

        if (body instanceof BaseResponse) {
            return body;
        } else if (body == null) {
            return BaseResponse.ok();
        } else {
            return BaseResponse.ok(body);
        }
    }
}

3 Add a return wrapper class


@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseResponse<T> {

    private T data;
    private int status = 200;
    private String message;
    private long srvTime = System.currentTimeMillis();

    public BaseResponse(String message) {
        this.message = message;
    }

    public BaseResponse<T> setData(T data) {
        this.data = data;
        return this;
    }

    public static <T> BaseResponse<T> ok() {
        return new BaseResponse<>(" Operation successful ");
    }

    public static <T> BaseResponse<T> ok(T data) {
        return new BaseResponse<T>(" Operation successful ").setData(data);
    }

}

4 Adding Control Classes


@Controller
@RequestMapping("/hello")
public class HelloWorld {

    //  Here the data is queried from the database ,  You can also use pseudo data instead of 
    @Autowired
    private UserMapper userMapper;

    // {@code ResponseEntity}  Case column 
    @GetMapping("/one")
    @ResponseBody
    public User one() {

        List<User> users = userMapper.selectAll();
        System.out.println(users.get(0));
        return users.get(0);
    }

    
    // {@code @ResponseBody}   Case column 
    @GetMapping("/list")
    @ResponseBody
    public List<User> list() {

        List<User> users = userMapper.selectAll();
        System.out.println(users);
        return users;
    }
}    

5 interface test

Browser access: http://localhost: 8080/hello/one


User(id=1, username= Li Ziqi , phone=77777, icon= The Head of Li Ziqi , queryTime=Wed Oct 27 20:47:02 CST 2021)
 Response interception succeeded 

Browser access: http://localhost: 8080/hello/list


[User(id=1, username= Li Ziqi , phone=77777, icon= The Head of Li Ziqi , queryTime=Wed Oct 27 20:46:58 CST 2021)]
 Response interception succeeded 

ps: If a direct response string returns, a type conversion exception is reported.


Related articles: