Say I have a class
class A {
public int x;
}
Then a valid json can be parsed as follows:
ObjectMapper mapper = new Obje
The main thing to do is to create a JsonParser
first, separately, then call ObjectMapper.readValue()
passing that parser, and THEN call nextToken()
once more and verify it returns null (instead of non-null value, or throw exception).
So, something like
JsonParser jp = mapper.getFactory().createParser(jsonSource);
try {
Value v = mapper.readValue(jp, Value.class);
if (jp.nextToken() != null) {
//throw some exception: trailing garbage detected
}
return v;
} finally {
jp.close();
}
Note: This is for Jackson 2.x. For Jackson 1.x, use getJsonFactory().createJsonParser()
instead of getFactory().createParser()
.
As of Jackson version 2.9, there is now DeserializationFeature.FAIL_ON_TRAILING_TOKENS which can be used to achieve that:
ObjectMapper objectMapper =
new ObjectMapper().enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
See https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.9 and https://medium.com/@cowtowncoder/jackson-2-9-features-b2a19029e9ff
You can have something like below.
Basically loop through the tokens before you readValue
.
JsonParser#nextToken() validates if your String is a proper JSON.
Here is the code:
public static void main(String[] args) throws JsonParseException, IOException {
ObjectMapper mapper = new ObjectMapper();
String str = "{\"x\" : 3} garbage";
JsonParser x = mapper.getJsonFactory().createJsonParser(str);
while(x.nextToken()!=null){
}
A a = mapper.readValue(str, A.class);
System.out.println(a);
}
console output:
Exception in thread "main" org.codehaus.jackson.JsonParseException: Unexpected character ('g' (code 103)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: java.io.StringReader@65faba46; line: 1, column: 12]
at org.codehaus.jackson.JsonParser._constructError(JsonParser.java:1432)
at org.codehaus.jackson.impl.JsonParserMinimalBase._reportError(JsonParserMinimalBase.java:385)
at org.codehaus.jackson.impl.JsonParserMinimalBase._reportUnexpectedChar(JsonParserMinimalBase.java:306)
at org.codehaus.jackson.impl.ReaderBasedParser._handleUnexpectedValue(ReaderBasedParser.java:1192)
at org.codehaus.jackson.impl.ReaderBasedParser.nextToken(ReaderBasedParser.java:479)
at example.JsonParse.main(JsonParse.java:21)