2014-11-05 17 views
14

Ho diversi controllori che restituiscono lo stesso oggetto Response generico con annotazione @ResponseBody, in questo modo:post elaborazione di una risposta JSON in primavera MVC

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

ho bisogno di eseguire un'operazione su ogni controller, dopo la La risposta viene restituita. Questa operazione arricchirà l'oggetto Response con nuovi dati.

Non voglio duplicare il codice, quindi ho bisogno di un singolo punto di intervento. Ho pensato che avrei potuto fare questo con Intercettori, però, secondo la documentazione http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor questo non funziona bene con @ResponseBody:

Si noti che il metodo di postHandle HandlerInterceptor non sempre è ideale per l'utilizzo con @ResponseBody e metodi ResponseEntity . In tali casi, HttpMessageConverter scrive e accetta la risposta prima che venga chiamato postHandle, il che rende impossibile modificare la risposta, ad esempio per aggiungere un'intestazione. Invece un'applicazione può implementare ResponseBodyAdvice e dichiararlo come un bean @ControllerAdvice o configurarlo direttamente su RequestMappingHandlerAdapter.

Non sono stato in grado di trovare un esempio di questa tecnica, qualcuno potrebbe aiutarmi?

In alternativa, potrei lavorare con aspetti, ma poi avrei bisogno di annotare tutti i controller, cosa che vorrei evitare.

risposta

22

Alla fine ho implementato ResponseBodyAdvice come questo:

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

} 

così è stato più facile del previsto.

Problemi correlati