Пост-обработка ответа Json в spring MVC

У меня есть несколько контроллеров, которые возвращают один и тот же общий объект Response с аннотацией @ResponseBody, например:

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

Мне нужно выполнить операцию на каждом контроллере после возвращения ответа. Эта операция обогатит объект Response новыми данными.

Я не хочу дублировать код, поэтому мне нужна единая точка вмешательства. Я думал, что могу сделать это с помощью Interceptors, однако, согласно документам http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor, это не работает с @ResponseBody:

Обратите внимание, что метод postHandle для HandlerInterceptor не всегда идеально подходит для использования с методами @ResponseBody и ResponseEntity. В таких случаях HttpMessageConverter записывает и передает ответ до того, как вызывается postHandle, что делает невозможным изменение ответа, например, для добавления заголовка. Вместо этого приложение может реализовать ResponseBodyAdvice и объявить его как @ControllerAdvice bean или настроить его непосредственно на RequestMappingHandlerAdapter.

Я не смог найти пример этой методики, может ли кто-нибудь помочь мне?

В качестве альтернативы я мог бы работать с аспектами, но тогда мне нужно было бы аннотировать каждый контроллер, чего я бы хотел избежать.

Ответы

Ответ 1

В конце я реализовал ResponseBodyAdvice следующим образом:

@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;
    }

}

Так было легче, чем ожидалось.