简体   繁体   中英

Spring Exception Handling using @ControllerAdvice

I have created an APIExceptionHandler class to handle custom Runtime Exceptions . One of the Exception classes that I have created is PasswordMismatchException . So whenever an exception is encountered I return a response of type APIResponse .

Now my question is why the expected Response is not getting generated when using CompletableFuture .

APIResponse.java

@AllArgsConstructor
@Getter
@Setter
public class APIResponse {
    private Map<String, String> response;
}

Exception Handler (CompletableFuture)

    @ExceptionHandler(PasswordMismatchException.class)
    public CompletionStage<ResponseEntity<APIResponse>> passwordMismatchExceptionHandler(PasswordMismatchException exception) {
        return CompletableFuture.completedFuture(Collections.singletonMap(MESSAGE_FIELD, exception.getMessage()))
                .thenApply(APIResponse::new)
                .thenApply(response -> new ResponseEntity<>(response, HttpStatus.BAD_REQUEST));
    }

Response (not as expected)

{
    "done": true,
    "cancelled": false,
    "completedExceptionally": false,
    "numberOfDependents": 0
}

Exception Handler (normal)

    @ExceptionHandler(PasswordMismatchException.class)
    public ResponseEntity<APIResponse> passwordMismatchExceptionHandler(PasswordMismatchException exception) {
        Map<String, String> errorMessageMap = Collections.singletonMap(MESSAGE_FIELD, exception.getMessage());
        APIResponse response = new APIResponse(errorMessageMap);
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }

Response (as expected)

{
    "response": {
        "message": "Password did not match with Repeated Password."
    }
}

In spring boot the ObjectMapper by default used the getters and setters for Serialization and Deserialization , while the response type is CompletionStage the object mapper will be serializing corresponding child object (for example CompletableFuture ) and serializing method starts with get and is

public boolean isDone()
public boolean isCancelled()
public boolean isCompletedExceptionally()
public int getNumberOfDependents()

And since then name of method is get which returns the final object, the objectmapper is simply ignoring it

public T get() throws InterruptedException, ExecutionException 

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