Reputation: 446
So I have this Controller class that contain this method:
@RequestMapping(value = "/x", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<MyRepsonseClass> get(
@ApiParam(value = "x", required = true) @Valid @RequestBody MyRequestClass request
) throws IOException {
//yada yada my logic here
return something;
}
The Json Request gets automatically Mapped to MyRequestClass.java
This is what that class looks like:
@lombok.ToString
@lombok.Getter
@lombok.Setter
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@ApiModel(description = "description")
public class MyRequestClass {
private List<SomeClass> attribute1;
private SomeOtherClass attribute2;
private YetAnotherClass attribute3;
}
This is an example of a valid json request:
{
"attribute1": [
{
"key":"value"
}
],
"attribute3": {
"key":"value"
}
}
Now, my requirement is to return an Error Message when the request contains an attribute that doesn't exist in the MyRequestClass.java.
As such:
{
"attribute1": [
{
"key":"value"
}
],
"attribute_that_doesnt_exist": {
"key":"value"
}
}
Right now it's not throwing any error. Rather, it's simply not mapping that attribute to anything. Are there annotations I can utilize that can make this happen quickly ?? Thank you.
Upvotes: 4
Views: 818
Reputation: 1600
Create a custom deserializer:
public class MyRequestClassDeserializer extends JsonDeserializer<MyRequestClass> {
@Override
public MyRequestClass deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
MyRequestClass mrc = new MyRequestClass();
ObjectMapper mapper = new ObjectMapper();
JsonToken currentToken = null;
while((currentToken = jsonParser.nextValue()) != null) {
if(currentToken.equals(JsonToken.END_OBJECT)
|| currentToken.equals(JsonToken.END_ARRAY))
continue;
String currentName = jsonParser.getCurrentName();
switch(currentName) {
case "attribute1":
List<SomeClass> attr1 = Arrays.asList(mapper.readValue(jsonParser, SomeClass[].class));
mrc.setAttribute1(attr1);
break;
case "attribute2":
mrc.setAttribute2(mapper.readValue(jsonParser, SomeOtherClass.class));
break;
case "attribute3":
mrc.setAttribute3(mapper.readValue(jsonParser, YetAnotherClass.class));
break;
// <cases for all the other expected attributes>
default:// it's not an expected attribute
throw new JsonParseException(jsonParser, "bad request", jsonParser.getCurrentLocation());
}
}
return mrc;
}
}
And add this annotation to your MyRequestClass
class: @JsonDeserialize(using=MyRequestClassDeserializer.class)
The only "problem" is that manually deserializing jsons can be a hassle. I would have written the complete code for your case but I'm not good enough at it right now. I might update the answer in the future.
Edit: Done, now it's working code. I thought it was more complicated.
Upvotes: 3
Reputation: 16465
Did you try this annotation @JsonIgnoreProperties(ignoreUnknown = false)
If Spring boot, even better, use this property in application.properties(yaml)
spring.jackson.deserialization.fail-on-unknown-properties=true
Upvotes: 1