Search code examples
javaspringhttp-status-code-400

Return a custom error message for 400 requests that don't hit the controller


I need to be able to return a custom error message for requests that are Bad Requests, but don't hit a controller (ex. Having bad JSON). Does anyone have any idea how to go about this? I tried the @ExceptionHandler annotation to no avail.

Any help would be appreciated.


Solution

  • Since Spring 3.2 you can add a ControllerAdvice like this

    import org.springframework.http.HttpStatus;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.ResponseStatus;
    
    @ControllerAdvice
    public class BadRequestHandler {
    
        @ResponseStatus(HttpStatus.OK)
        @ExceptionHandler(HttpMessageNotReadableException.class)
        @ResponseBody
        public ErrorBean handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
            ErrorBean errorBean = new ErrorBean();
            errorBean.setMessage(e.getMessage());
            return errorBean;
        }
    
        class ErrorBean {
            private String message;
    
            public String getMessage() {
                return message;
            }
    
            public void setMessage(String message) {
                this.message = message;
            }
        }
    }
    

    In handleHttpMessageNotReadableException, which is annotated with @ExceptionHandler(HttpMessageNotReadableException.class), you can handle the exception and render a custom response. In this case a ErrorBean becomes populated and return to the client. If Jackson is available on classpath and Content-Type was set to application/json by the client, this ErrorBean gets returned as json.