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.
2 Answers
Answers 1
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.
Answers 2
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
0 comments:
Post a Comment