Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How return error message in spring mvc @Controller

I am using methods like this

@RequestMapping(method = RequestMethod.GET) public ResponseEntity<UserWithPhoto> getUser(@RequestHeader(value="Access-key") String accessKey,                                      @RequestHeader(value="Secret-key") String secretKey){     try{         return new ResponseEntity<UserWithPhoto>((UserWithPhoto)this.userService.chkCredentials(accessKey, secretKey, timestamp),                 new HttpHeaders(),                 HttpStatus.CREATED);     }     catch(ChekingCredentialsFailedException e){         e.printStackTrace();         return new ResponseEntity<UserWithPhoto>(null,new HttpHeaders(),HttpStatus.FORBIDDEN);     } } 

And I want to return some text message when exception occurs but now I just return status and null object. Is it possible to do?

like image 552
user3378876 Avatar asked Sep 07 '15 15:09

user3378876


People also ask

How do I send an error response in Spring?

Instead of passing a null argument for your error case, pass in a String . Spring is smart enough to see the String and write it as text to the response body. Alternatively, provide a @ExceptionHandler that will handle the exception itself and have your handler throw the exception.

How do I return a Spring boot error?

Return a Generic Error Message using @ResponseStatus The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field.


2 Answers

As Sotirios Delimanolis already pointed out in the comments, there are two options:

Return ResponseEntity with error message

Change your method like this:

@RequestMapping(method = RequestMethod.GET) public ResponseEntity getUser(@RequestHeader(value="Access-key") String accessKey,                               @RequestHeader(value="Secret-key") String secretKey) {     try {         // see note 1         return ResponseEntity             .status(HttpStatus.CREATED)                              .body(this.userService.chkCredentials(accessKey, secretKey, timestamp));     }     catch(ChekingCredentialsFailedException e) {         e.printStackTrace(); // see note 2         return ResponseEntity             .status(HttpStatus.FORBIDDEN)             .body("Error Message");     } } 

Note 1: You don't have to use the ResponseEntity builder but I find it helps with keeping the code readable. It also helps remembering, which data a response for a specific HTTP status code should include. For example, a response with the status code 201 should contain a link to the newly created resource in the Location header (see Status Code Definitions). This is why Spring offers the convenient build method ResponseEntity.created(URI).

Note 2: Don't use printStackTrace(), use a logger instead.

Provide an @ExceptionHandler

Remove the try-catch block from your method and let it throw the exception. Then create another method in a class annotated with @ControllerAdvice like this:

@ControllerAdvice public class ExceptionHandlerAdvice {      @ExceptionHandler(ChekingCredentialsFailedException.class)     public ResponseEntity handleException(ChekingCredentialsFailedException e) {         // log exception         return ResponseEntity                 .status(HttpStatus.FORBIDDEN)                 .body("Error Message");     }         } 

Note that methods which are annotated with @ExceptionHandler are allowed to have very flexible signatures. See the Javadoc for details.

like image 68
hzpz Avatar answered Sep 25 '22 17:09

hzpz


Here is an alternative. Create a generic exception that takes a status code and a message. Then create an exception handler. Use the exception handler to retrieve the information out of the exception and return to the caller of the service.

http://javaninja.net/2016/06/throwing-exceptions-messages-spring-mvc-controller/

public class ResourceException extends RuntimeException {      private HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;      public HttpStatus getHttpStatus() {         return httpStatus;     }      /**      * Constructs a new runtime exception with the specified detail message.      * The cause is not initialized, and may subsequently be initialized by a      * call to {@link #initCause}.      * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()}      *                method.      */     public ResourceException(HttpStatus httpStatus, String message) {         super(message);         this.httpStatus = httpStatus;     } } 

Then use an exception handler to retrieve the information and return it to the service caller.

@ControllerAdvice public class ExceptionHandlerAdvice {       @ExceptionHandler(ResourceException.class)     public ResponseEntity handleException(ResourceException e) {         // log exception          return ResponseEntity.status(e.getHttpStatus()).body(e.getMessage());     }          }  

Then create an exception when you need to.

throw new ResourceException(HttpStatus.NOT_FOUND, "We were unable to find the specified resource."); 
like image 40
Norris Avatar answered Sep 22 '22 17:09

Norris