Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

This works when I throw a BadRequestException from my controller but the reason is always "Invalid parameter" of course. Is there a way to set the returned reason in this class? I'd like to pass a string to be used as the reason.

Thanks!

like image 260
Paul Avatar asked Dec 21 '11 18:12

Paul


People also ask

What is the effect of annotating a method with @ResponseStatus?

Annotation Type ResponseStatusMarks a method or exception class with the status code() and reason() that should be returned. The status code is applied to the HTTP response when the handler method is invoked and overrides status information set by other means, like ResponseEntity or "redirect:" .

How do you use ResponseStatus?

We can use @ResponseStatus to mark a method or an exception class with a status code and reason that should be returned. On invoking the marked handler method or when a specified exception is thrown, the HTTP status will be set to the one defined using @ResponseStatus annotation.

How do I change my spring boot response code?

If we want to specify the response status of a controller method, we need to annotate that method with the @ResponseStatus annotation. It has two interchangeable arguments for the desired response type: code and value. Note, that when we set reason, Spring calls HttpServletResponse. sendError().


2 Answers

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 - in your service layer. Thus you don't need a catch and throw something else or catch in the controller to set the response directly to some HTTP status code.

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. So you can have say one basic exception for a given context and use it in a dozen places, each with a slightly differing message where it is thrown and all get's handled properly out to the REST interface.

like image 166
Randy Avatar answered Sep 17 '22 20:09

Randy


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"); } 
like image 25
Bozho Avatar answered Sep 19 '22 20:09

Bozho