简体   繁体   中英

Spring Boot human readable error messages after JSON parsing error

I have a REST API written using Spring Boot. Now I would like to to enhance error handling. If user sends either not valid JSON or JSON which can not me deserialized to my DTO I would to inform user what exactly was wrong, eg unexpected property name, type etc. Still I don't want to expose any information about the implementation (eg stacktrace, class names).

Default Spring implementation returns

InvalidFormatException: Cannot deserialize value of type `java.lang.Integer` from String \"aaa\": not a valid Integer value\n at [Source: (PushbackInputStream); line: 10, column: 19]
 (through reference chain: com.yell.statementofwork.model.StatementOfWorkCompletionDtoSe[\"purchasedProducts\"]->java.util.ArrayList[0]->com.yell.statementofwork.model.PurchasedProductDtoSe[\"quantity\"])",

which is almost good but I would prefer to remove information about class from it. Do you have any proposition how to do that?

you can create your own custom ConstraintValidator and annotate your DTO object with corresponding annotation

you can find the example here - http://dolszewski.com/spring/custom-validation-annotation-in-spring/

PS the example is using annotation for one field, but you can use it on the whole class

The cleanest way to handle different types of errors in a spring boot REST API is by using spring AOP. First, let's create a custom Exception class

public class InvalidFormatException extends RuntimeException {

    private final String message;
    private final List<String> data;

    // getters , setters and constructors
}

Then create an error response model class. This model class will provide a JSON structure of what should sent back to the user in case of an exception

public class ErrorResponseModel {
    
    String code;
    String type;
    String message;
    List<String> data;

    // getters, setters, and constructor
}

Then create a custom exception handler for your controller using spring AOP

@ControllerAdvice
public class ControllerExceptionHandler {

    @ExceptionHandler(InvalidFormatException.class)
    public ResponseEntity<ErrorResponseModel> badRequestException(InvalidFormatException ex, WebRequest request) {
        return new ResponseEntity<>(new ErrorResponseModel(ex.getMessage(), ex.getData()),
                HttpStatus.BAD_REQUEST);
    }
}

You can add and handle more error types like this in this class. Now whenever you throw an Exception, it will be intercepted here and a custom error response will be sent back to the user.

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