Pregunta Spring Mvc Interceptor: acceso a ResponseEntity en PostHandle


Tengo un interceptor que registra el resultado de las respuestas de Spring MVC. Todas mis respuestas devuelven objetos ResponseEntity que tienen contenido de cuerpo JSON.

Me gustaría obtener tanto el cuerpo de respuesta como el estado de http de ResponseEntity.

¿Cómo puedo obtener acceso a ResponseEntity desde los atributos del método postHandle?

public void postHandle(HttpServletRequest request, 
    HttpServletResponse response, 
    Object handler, 
    ModelAndView modelAndView) {}

El atributo modelAndView es nulo para mis invocaciones.

Gracias, Jason


6
2018-04-04 20:26


origen


Respuestas:


Cuando escribiste tu pregunta, creo que no era posible, pero ahora lo es. De sus documentos http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-intercepto

"Tenga en cuenta que el método postHandle de HandlerInterceptor no siempre es ideal para su uso con los métodos @ResponseBody y ResponseEntity. En tales casos, HttpMessageConverter escribe y confirma la respuesta antes de llamar a postHandle, lo que hace imposible cambiar la respuesta, por ejemplo, agregar En su lugar, una aplicación puede implementar ResponseBodyAdvice y declararlo como un bean @ControllerAdvice o configurarlo directamente en RequestMappingHandlerAdapter "


2
2017-07-20 11:34



He encontrado una solución completa, y una solución parcial.

Solución parcial: Para aquellos que utilizan Servlet 3.0, el código HTTPStatus está disponible en el objeto HttpServletResponse. Esto habría resuelto la mitad de mi problema en que puedo obtener el código de estado, pero aún así no me dio acceso a la Entidad de Respuesta que tiene el atributo de cuerpo que quería inspeccionar.

Solución completa (funciona en Servlet 2.x): Usé una combinación de un Aspecto y un Interceptor.

El Aspecto fue codificado para apuntar a @AfterReturn de los métodos del controlador que devuelven ResponseEntities. Básicamente, capturó la answerEntity devuelta y la puso en una colección <ResponseEntity> ThreadLocal.

Luego, el Interceptor le pidió al Aspecto la respuesta del subproceso y TA-DAH fue accesible.

Espero que esta respuesta ayude a alguien más. Aclamaciones, Jason


1
2018-04-19 22:02



@ControllerAdvice
public class ResponseDTOFilterAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(final MethodParameter returnType, final Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(final Object body, final MethodParameter returnType, final MediaType selectedContentType,
        final Class<? extends HttpMessageConverter<?>> selectedConverterType, final ServerHttpRequest request,
        final ServerHttpResponse response) {
        if (body instanceof ResponseDTO<?>) {
            ResponseDTO<?> responseDTO = (ResponseDTO<?>) body;
            responseDTO.setHostname(request.getLocalAddress().getHostName());
        }
        return body;
    }
}

Fuente: Post procesamiento de una respuesta Json en la primavera MVC


0
2018-05-24 17:48