Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I enable strict validation of JSON / Jackson @RequestBody in Spring Boot REST API?

How do I throw an error if extra parameters are specified in the JSON request? For example, "xxx" is not a valid parameter or in the @RequestBody object.

$ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"apiKey": "'$APIKEY'", "email": "[email protected]", "xxx": "yyy"}' localhost:8080/api/v2/stats

I tried adding @Validated to the interface, but it didn't help.

@RequestMapping(value = "/api/v2/stats", method = RequestMethod.POST, produces = "application/json")
public ResponseEntity<DataResponse> stats(Principal principal, @Validated @RequestBody ApiParams apiParams) throws ApiException;

I would like to enable a 'strict' mode so that it will give an error if extra, spurious parameters exist in the request. I could find no way to do this. I found ways to ensure the valid parameters do exist, but no way to ensure there are not extra parameters.


public class ApiParams extends Keyable {

    @ApiModelProperty(notes = "email of user", required = true)
    String email;

public abstract class Keyable {

    @ApiModelProperty(notes = "API key", required = true)
    @NotNull
    String apiKey;

Spring Boot 1.5.20

like image 571
Chloe Avatar asked May 09 '19 04:05

Chloe


People also ask

How do you validate query parameters in spring boot?

Validating a PathVariable Just as with @RequestParam, we can use any annotation from the javax. validation. constraints package to validate a @PathVariable. The default message can be easily overwritten by setting the message parameter in the @Size annotation.

What is @valid annotation in spring boot?

The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.


1 Answers

Behind the scene, Spring uses the Jackson library to serialize/deserialize POJO to JSON and vice versa. By default, the ObjectMapper that the framework uses to perform this task has its FAIL_ON_UNKNOWN_PROPERTIES set to false.

You can turn this feature on GLOBALLY by setting the following config value in application.properties.

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

Or if using YAML format, add the following to your application.yaml (or .yml) file):

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

Subsequently, if you want to ignore unknown properties for specific POJO, you can use the annotation @JsonIgnoreProperties(ignoreUnknown=true) in that POJO class.


Still, this could mean a lot of manual work going forward. Technically, ignoring those unexpected data doesn't violate any software development principles. There might be scenarios where there's a filter or servlet sitting in front of your @Controller doing additional stuff that you're not aware of which requires those extra data. Does it seem worth the effort?

like image 98
Mr.J4mes Avatar answered Oct 04 '22 02:10

Mr.J4mes