MEZesUBI
MEZesUBI

Reputation: 307

How to restrict JSON payload from containing additional fields with Spring?

I have a basic User DTO class...

public class User {

  @JsonProperty("firstName")
  private String firstName;

  @JsonProperty("lastName")
  private String lastName;
}

...and a basic request handler in a @RestController class:

@RequestMapping(path = "/users", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE })
public UserMessage createUser(@RequestBody User user){
   return userService.createUser(user);
}

How can I restrict incoming JSON payloads to contain at most only the required keys? i.e. accept this payload:

{
  "firstName":"foo",
  "lastName":"bar"
}

And throw a custom exception on this:

{
  "firstName":"foo",
  "lastName":"bar",
  "type":"admin",
  "asdf":"asdf"
}

I read about custom Converters, ArgumentResolvers, and I believe I could simply put an additional Map parameter in the handler and validate before service call, however I'd like to know the "best" way of handling this issue.

Upvotes: 0

Views: 1907

Answers (2)

MEZesUBI
MEZesUBI

Reputation: 307

Solved the issue, this thread helped @JsonIgnoreProperties(ignoreUnknown=false) is not working in Spring 4.2.0 and upper version

mle, your answer wasn't right, since I was using the latest version of Spring Framework and the ObjectMapper's FAIL_ON_UNKNOWN_PROPERTIES is turned off by default. Additionally I was needed to set @JsonIgnoreProperties(ignoreUnknown = false) in my User DTO class (as the actual class' superclass had this set to true).

Tested it, runs like a charm, while custom errors can be handled in a @ExceptionHandler(HttpMessageNotReadableException.class) annotated handler.

Upvotes: 1

mle
mle

Reputation: 2550

Regarding the User bean in your example it also already not possible, that potential other JSON fields than firstName and lastName could be mapped, simply because there are no fields in User which could hold the relevant data.

Should the User bean in your question be not complete, e.g. for simplicity reasons, and contain more fields, also then should everything be fine, as long as you did not configure your your ObjectMapper with com.fasterxml.jackson.databind.DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES => false or you use the annotation @JsonIgnoreProperties(ignoreUnknown = true) on your bean.

To sum it up: Jackson's default behavior is FAIL_ON_UNKNOWN_PROPERTIES (default: true)

For further information you can also consult the respective Deserialization docs.

Upvotes: 1

Related Questions