responseentity example controlleradvice advice java spring spring-mvc

java - example - En Spring 3, ¿es posible establecer dinámicamente la razón de @ResponseStatus?



spring response exception handler (6)

Tengo una clase de excepción personalizada anotada para devolver un HttpStatus dado:

@ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Invalid parameter") public class BadRequestException extends RuntimeException { public BadRequestException(String msg) { super(msg); } }

Esto funciona cuando lanzo una BadRequestException desde mi controlador, pero la razón es siempre "Parámetro no válido", por supuesto. ¿Hay una manera de establecer la razón devuelta en esta clase? Me gustaría pasar una cadena para ser utilizada como la razón.

¡Gracias!



La forma correcta es introducir un controlador de excepciones en su controlador, luego puede configurar el cuerpo de respuesta de cualquier código de estado:

@Controller @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) public class SomeController { ... @ExceptionHandler(BadRequestException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public @ResponseBody Map<String,Object> handleIndexNotFoundException(BadRequestException bre, HttpServletRequest request, HttpServletResponse resp) { HashMap<String, Object> result = new HashMap<>(); result.put("error", true); result.put("error_message", bre.getMessage()); return result; } }

Al moverte, no tienes que contaminar tus clases de modelo / excepción con ninguna de las anotaciones y dependencias de Spring Web MVC.

Si desea compartir el controlador con todos los controladores, consulte @ControllerAdvice .


La forma más fácil de configurar simplemente response.setStatus() . Fácil y limpio, puede cambiarlo a cualquier estado que desee simplemente en lugar de que ex.getStatusCode() agregue su código.

El tipo de retorno también es de su elección, estoy usando String b / c, que se muestra más adelante.

Por cierto, sendError no es una buena idea, porque JBoss, por ejemplo, está agregando mucho HTML a la respuesta.

@ExceptionHandler(CommunicationException.class) @ResponseBody() public String handleCommunicationException(CommunicationException ex, HttpServletResponse response) throws IOException{ response.setStatus(ex.getStatusCode()); return ex.getStatusMessage(); }


Las anotaciones están destinadas a ser estáticas y no se pueden establecer dinámicamente desde su clase. Sugiero crear una subclase de su BadRequestException para cada tipo de escenario de falla y anotarlas de manera diferente.

Esto no solo sirve como solución alternativa: si está ocultando los detalles sobre lo que salió mal en el mensaje de reason , perderá flexibilidad porque cualquier código que BadRequestException una BadRequestException tendrá que lidiar con todos los escenarios de falla de la misma manera. camino.


Puede usar response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid foo");


Si omite el atributo ''motivo'' en la anotación @ResponseStatus en una excepción personalizada,

@ResponseStatus(value = HttpStatus.CONFLICT) // 409 public class ChildDataExists extends RuntimeException { ...

luego lanza la excepción

throw new ChildDataExists("Can''t delete parent if child row exists.");

El mensaje de la excepción aparece como el ''mensaje'' de los ''datos'' en la salida JSON. Parece que la ''razón'' en la anotación anula el comportamiento personalizado.