简体   繁体   中英

Spring Boot Global Exception Handler does not Capture HttpMessageNotReadableException

I have a global exception handler, which works fine to capture exceptions thrown from my controller, service layer, or repository layer. However, it fails to capture exceptions that occur before entering my controller. Specifically, I have a POST controller that expects a valid json body, if the actual json body is malformed, an HttpMessageNotReadableException is thrown, and I have no idea where this exception got handled. The response code is indeed 400 . So my question is, how to use my own logic to capture and handle message deserialization exception that happens before entering my controller.

My global exception handler (it works fine for exceptions thrown from my service layer)

@ControllerAdvice(basePackageClasses = TopologyApiController.class)
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
  private static final String UNKNOWN_SERVER_ERROR_MSG = "Unknown server error";

  @ExceptionHandler(value = {ServiceException.class})
  public ResponseEntity<ErrorResponse> handleServiceException(Exception ex, WebRequest request) {
    // some handling
    return generateExceptionResponseEntity(errorMessage, status);
  }

  @ExceptionHandler(value = {Exception.class})
  public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex, WebRequest request) {
    return generateExceptionResponseEntity(UNKNOWN_SERVER_ERROR_MSG, HttpStatus.INTERNAL_SERVER_ERROR);
  }

  private ResponseEntity<ErrorResponse> generateExceptionResponseEntity(String message, HttpStatus status) {
    ErrorResponse response = new ErrorResponse();
    response.setMessage(message);
    return ResponseEntity.status(status).body(response);
  }
}

My POST controller (expects a json body to deserialize into a CityInfo object)

@RequestMapping(value = API_BASE + "/topology/cities", method = RequestMethod.POST)
ResponseEntity<CityInfo> topologyCitiesPost(@Valid @RequestBody CityInfo body) {
  CityInfo cityInfo = topologyService.addCity(body);
  return ResponseEntity.status(HttpStatus.CREATED).body(cityInfo);
}

The controller expects a json body in the form of below, and the entire code works fine if the json is valid.

{
  "description": "string",
  "name": "string",
  "tag": "string"
}

but if the actual content is something like below (eg, with several commas at the end), an HttpMessageNotReadableException will be thrown and is not captured by my handler.

{
  "description": "this is description",
  "name": "city name",
  "tag": "city tag",,,,
}

This: So my question is, how to use my own logic to capture and handle message deserialization exception that happens before entering my controller.

Annotate and write an exceptionHandler for that specific exception. Add this to your GlobalExceptionHandler class:

@ExceptionHandler(HttpMessageNotReadableException.class)
  public ResponseEntity<ErrorResponse> handleMessageNotReadableException(Exception ex, WebRequest request) {
    // some handling
    return generateExceptionResponseEntity(errorMessage, status);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM