Say I have a class
class A {
public int x;
}
Then, valid json can be parsed as follows:
ObjectMapper mapper = new ObjectMapper();
A a = mapper.readValue("{\"x\" : 3}", A.class);
Is there a way for the parser to fail if the string contains more data than is needed to parse the object?
For example, I would like to accomplish the following (which is successful)
A a = mapper.readValue("{\"x\" : 3} trailing garbage", A.class);
I tried it using InputStream with JsonParser.Feature.AUTO_CLOSE_SOURCE = false and checking if the stream was completely consumed, but this does not work:
A read(String s) throws JsonParseException, JsonMappingException, IOException {
JsonFactory f = new MappingJsonFactory();
f.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
ObjectMapper mapper = new ObjectMapper(f);
InputStream is = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
try {
A a = mapper.readValue(is, A.class);
if(is.available() > 0) {
throw new RuntimeException();
}
return a;
} finally {
is.close();
}
}
those.
read("{\"x\" : 3} trailing garbage");
still succeeds, perhaps because the parser consumes more from the stream than necessary.
One solution that works is to verify that the parsing does not work when discarding the last character from a string:
A read(String s) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
A a = mapper.readValue(s, A.class);
if (s.length() > 0) {
try {
mapper.readValue(s.substring(0, s.length()-1), A.class);
throw new RuntimeException();
} catch (JsonParseException e) {
}
}
return a;
}
but I am looking for a more effective solution.