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.