0

We have a spring boot based rest api that accepts http post requests from multiple consumers in json. It can't accept requests with unknown fields and needs to give a response that says that it is a bad request and meaningfully describe the error. However, for security reasons, we only need to give them just enough error information.

Here's what we have so far:

To achive it, here's what we have done so far:

The application properties file has this:
spring.jackson.deserialization.fail-on-unknown-properties=true

The exception handling has been customized like so (other functionality is omitted for brevity):

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

    Logger logger = LoggerFactory.getLogger(RestExceptionHandler.class);

    @Override
    public ResponseEntity<Object> handleHttpMessageNotReadable(
            HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

        //this message can't give them info about known properties
        exceptionMessage = ex.getLocalizedMessage();
        logger.debug("exceptionMessage: " + ex.getLocalizedMessage());

        //ApiError is a custom object to encapsulate the information to be sent in the api response.
        ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, "HTTP message not readable", exceptionMessage);
        apiError.setHttpStatus(HttpStatus.BAD_REQUEST);
        apiError.setErrorMessage(errorMessage);

        return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getHttpStatus());
    }
}

A json request containing an unknown-field would result in the following exception:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "unknown-field" (class mypackage.MyDomain), not marked as ignorable (2 known properties: "known-field-1", "known-field-2"])

We don't want to give out details about the known properties for security reasons (2 known properties: "known-field-1", "known-field-2"]).

Request body:

{"known-field-1": 1, "unknown-field": 2}

Actual response body:

{"status":"BAD_REQUEST","message":"HTTP message not readable","errors":[Unrecognized field "unknown-field" (class mypackage.MyDomain), not marked as ignorable (2 known properties: "known-field-1", "known-field-2"]}

Desired response body:

{"status":"BAD_REQUEST","message":"HTTP message not readable","errors":["Unknown field: unknown-field"]}

How to further customize this easily?

3
  • Can you add your current response and expected response? Commented Oct 16, 2018 at 15:35
  • in your ApiError object dont send exceptionMessage as this is actual error message thrown..instead of it send custom error message string like something "There are unknown properties in request, please check API contract for detail" Commented Oct 16, 2018 at 16:06
  • Thanks for looking into this. It wasn't too difficult after all. Commented Oct 16, 2018 at 17:53

1 Answer 1

1

This solved it:

@Override
public ResponseEntity<Object> handleHttpMessageNotReadable(
        HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

    String exceptionMessage = null;

    Throwable rootCause = ex.getRootCause();
    if(rootCause instanceof UnrecognizedPropertyException)
    {
        exceptionMessage = "Unknown field: " + ((UnrecognizedPropertyException) rootCause).getPropertyName();
        logger.debug("exceptionMessage: " + exceptionMessage);
    }

    ApiError apiError = 
      new ApiError(HttpStatus.BAD_REQUEST, "HTTP message not readable", exceptionMessage);

    return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.