In Spring 3 is it possible to dynamically set the reason of @ResponseStatus?

后端 未结 7 1935
别跟我提以往
别跟我提以往 2021-02-05 02:01

I have a custom exception class annotated to return a given HttpStatus:

@ResponseStatus(value=HttpStatus.BAD_REQUEST, reason=\"Invalid parameter\")
         


        
相关标签:
7条回答
  • 2021-02-05 02:06

    The "reason" is optional, so you can omit that and implements the abstract method public String reason passing the Error. Link: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/ResponseStatus.html

    0 讨论(0)
  • 2021-02-05 02:07

    Since spring 5.0, you can use the ResponseStatusException which is available

    // From https://www.baeldung.com/spring-response-status-exception
    @GetMapping("/actor/{id}")
    public String getActorName(@PathVariable("id") int id) {
        try {
            return actorService.getActor(id);
        } catch (ActorNotFoundException ex) {
            throw new ResponseStatusException(
              HttpStatus.NOT_FOUND, "Actor Not Found", ex);
        }
    }
    
    0 讨论(0)
  • 2021-02-05 02:09

    The easiest way to just set the response.setStatus(). Easy and clean, you can change it to any status you want just instead of ex.getStatusCode() add your code.

    The return type is also of your choice, I'm using String b/c displaying this later.

    By the way, the sendError is not a good idea, because JBoss for instance is adding a lot of HTML to the response.

    @ExceptionHandler(CommunicationException.class)
    @ResponseBody()
    public String handleCommunicationException(CommunicationException ex, HttpServletResponse response) throws IOException{
        response.setStatus(ex.getStatusCode());
        return ex.getStatusMessage();   
    }
    
    0 讨论(0)
  • 2021-02-05 02:10

    The correct way is to introduce exception handler in your controller, then you can set response body of any status code:

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

    Move over you don't have to pollute your model/exception classes with any Spring Web MVC annotations and dependency.

    If you want to share the handler with all controller look into @ControllerAdvice.

    0 讨论(0)
  • 2021-02-05 02:12

    You can use HttpServletResponse's sendError function to achieve that.
    Here is an example of how to use it:

    @RequestMapping(value = "some/url", method = RequestMethod.POST)
    public void doAction(final HttpServletResponse response) throws IOException {
      response.sendError(HttpStatus.BAD_REQUEST.value(), "custom error message");
    }
    
    0 讨论(0)
  • 2021-02-05 02:18

    If you omit the 'reason' attribute in the @ResponseStatus annotation on a custom exception,

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

    then throw the exception

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

    The exception's message comes through as the 'message' of the 'data' in the JSON output. It seems the 'reason' in the annotation overrides the custom behavior.

    0 讨论(0)
提交回复
热议问题