Home > database >  Return error on unknown fields in JSON request body of specific controllers
Return error on unknown fields in JSON request body of specific controllers

Time:02-02

I have SpringBoot application X that has customer facing APIs. Those APIs receive request body as JSON.

Application X issues API calls to application Y and receives responses with JSON body.

I want to prevent application X from receiving unknown fields in the request body on customer-facing controllers.

I was thinking about spring.jackson.deserialization.fail-on-unknown-properties=true but if I understand correctly such configuration will cause a failure also if a call from application X to application Y will return response body with unknown field. Therefore this configuration will make the API between application X and application Y more coupled and less robust.

I am looking for a way to enforce "fail-on-unknown-fields" only for deserialization of request body at customer facing controllers of an application while allowing deserialization at other parts of the application to ignore unknown fields

Example: I have the following customer facing API.

@PostMapping
public Response updateProduct(@RequestBody Product product) {
.....
}

Where

class Product {
    private int id;
    private String name;
    private int price;
}

I want to prevent customer from passing the following body to request, because colour is not a know field.

{
  "id": 777,
  "name": "apple",
  "price": 2,
  "colour": "red"
}

But - I want it the "fail-unknown-fields" to be enforced on this controller only and not at other places where Jackson is used to deserialized responses received from other applications.

CodePudding user response:

You can create a new ObjectMapper instance in your controller explicitly configuring its DeserializationFeature#FAIL_ON_IGNORED_PROPERTIES to the value true that will force the fail in the case of unknown properties inside the json in the post request body like below:

@PostMapping(value = "/updateproduct")
public Product updateProduct(@RequestBody String productString) throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, true);
    //it will fail in case of unknown properties inside the json string
    Product product = objectMapper.readValue(productString, Product.class);
    return product;
}

Choosing to convert the request body json to String you can configure manually your ObjectMapper local instance while you have to decide how to proceed when there is a json processing exception (in my case I simply decided to directly throw the exception but a different behaviour can be adopted) or the UnrecognizedPropertyException exception like the case you presented.

CodePudding user response:

To change this on project level, you can add on your application.properties the following content:

spring.jackson.deserialization.fail-on-unknown-properties=true

Or if you are using an application.yaml:

spring:
  jackson:
    deserialization:
      fail-on-unknown-properties: true

This configuration will affect on project level, so you can keep using the correct DTO on the @RequestBody object received. This way, you don't have to do any change on your controller, but may be advisable to control the exception in your @ControllerAdvice.

  • Related