Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post processing of a Json response in spring MVC

I have several controllers that return the same generic Response object with @ResponseBody annotation, like this:

@RequestMapping(value = "/status", method = RequestMethod.GET)
    @Transactional(readOnly = true)
    public @ResponseBody Response<StatusVM> status()

I need to perform an operation on every controller, after the Response is returned. This operation will enrich the Response object with new data.

I don't want to duplicate code, so I need a single point of intervention. I thought I could do this with Interceptors, however, according to the docs http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor this does not work well with @ResponseBody:

Note that the postHandle method of HandlerInterceptor is not always ideally suited for use with @ResponseBody and ResponseEntity methods. In such cases an HttpMessageConverter writes to and commits the response before postHandle is called which makes it impossible to change the response, for example to add a header. Instead an application can implement ResponseBodyAdvice and either declare it as an @ControllerAdvice bean or configure it directly on RequestMappingHandlerAdapter.

I haven't been able to find an example of this tecnique, could anybody help me?

As an alternative I could work with aspects, but then I'd need to annotate every controller, which is something I'd like to avoid.

like image 807
LittleSquinky Avatar asked Nov 05 '14 12:11

LittleSquinky


People also ask

How pass JSON object in post request in spring boot?

Send JSON Data in POST Spring provides a straightforward way to send JSON data via POST requests. The built-in @RequestBody annotation can automatically deserialize the JSON data encapsulated in the request body into a particular model object. In general, we don't have to parse the request body ourselves.

How do I return a JSON response?

To return JSON from the server, you must include the JSON data in the body of the HTTP response message and provide a "Content-Type: application/json" response header. The Content-Type response header allows the client to interpret the data in the response body correctly.

What is @ResponseBody annotation in spring?

The @ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object.

How do you use RequestBody?

@RequestBody : Annotation indicating a method parameter should be bound to the body of the HTTP request. @ResponseBody annotation can be put on a method and indicates that the return type should be written straight to the HTTP response body (and not placed in a Model, or interpreted as a view name).


1 Answers

In the end I implemented ResponseBodyAdvice like this:

@ControllerAdvice
public class StatusAdvice implements ResponseBodyAdvice<Response<?>> {


    @Override
    public boolean supports(MethodParameter returnType,
            Class<? extends HttpMessageConverter<?>> converterType) {

        if (returnTypeIsReponseVM(returnType)&&responseConverterIsJackson2(converterType)){
            return true;
        }

        return false;
    }

....

    @Override
    public Response<?> beforeBodyWrite(Response<?> body, MethodParameter returnType,
            MediaType selectedContentType,
            Class<? extends HttpMessageConverter<?>> selectedConverterType,
            ServerHttpRequest request, ServerHttpResponse response) {

        ....

        return body;
    }

}

So it was easier then expected.

like image 69
LittleSquinky Avatar answered Oct 10 '22 12:10

LittleSquinky