Error handling on controller SpringMVC

2019-04-17 15:37发布

问题:

I am developing an application in jax-rs and spring mvc. I want to notify my client each time when an default error is occured like 400, 403, 404, 405 and 415.

Controller

    @Controller
    @RequestMapping("/customer")
    public class CustomerController {

        @Autowired
        CustomerService customerService;

        // ........xxxxxx..............xxxxxxx................xxxxxxx.............//


            @CrossOrigin
            @RequestMapping(value = "/", 
                            method = RequestMethod.GET, 
                            produces = MediaType.APPLICATION_JSON_VALUE)
            public @ResponseBody String fetchCustomer() throws JsonProcessingException {
                return new ObjectMapper().writeValueAsString(customerService.fetchAllCustomer());
            }

            // ........xxxxxx..............xxxxxxx................xxxxxxx.............//

}  

Client

$http({
        method: "GET",
        contentType: "application/json",
        url: baseUrl + '/customer'
      }).success(function (response) {
        console.log(response);
        // you can also use
        console.log(JSON.stringify(response);
      }).error(function (response) {
        console.log(response);
      });

When i request a service from client i want to send response back with status code and custom message.

Example

When i defind method = post on controller and from client i send request as get service should return message like

error:{
     Status Code: 405,
     Message:  Invalid Method 
     url: error/405
}

回答1:

Check this out for reference.

Define a method for handling the specific error scenario and annotate it as @ExceptionHandler. The exception in your scenario (request method not supported) is HttpRequestMethodNotSupportedException.class. You can create more generic handler methods using Throwable, Exception etc.

In order to prevent duplication of error handling across controllers, one convenient way is to define all handlers in single class and use @ControllerAdvice on that. This way, all handlers will be applied to all controllers.



回答2:

Do not return a String but return a org.springframework.http.ResponseEntity. You can add status codes to this object

ResponseEntity<String> responseEntity = new ResponseEntity<String>("This is a response", HttpStatus.INTERNAL_SERVER_ERROR);
return responseEntity;

So your method signature will also change as below

    @RequestMapping(value = "/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody ResponseEntity<String> fetchCustomer() throws JsonProcessingException {
        try {
            String str = new ObjectMapper().writeValueAsString(customerService.fetchAllCustomer());
            return new ResponseEntity<String>(str, HttpStatus.OK);
         }
        catch (Exception e) {
             return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

If there is an error, you can either use controller advice or catch the exception and update the ResponseEntity appropriately