Weird behavior when deserializing from JSON array
NoahELE opened this issue · comments
Search before asking
- I searched in the issues and found nothing similar.
Describe the bug
I try to deserialize a Point class from an array of 2, e.g. "[1,1]".
When using JsonDeserializer
, the first token read is not an JsonToken.START_ARRAY
.
Version Information
2.17.0
Reproduction
public class Point {
public int x;
public int y;
}
public class PointDeserializer extends JsonDeserializer<Point> {
@Override
public Point deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JacksonException {
if (jp.nextToken() != JsonToken.START_ARRAY) {
throw new JsonParseException(jp, "Expected array start");
}
if (jp.nextToken() != JsonToken.VALUE_NUMBER_INT) {
throw new JsonParseException(jp, "Expected int");
}
int x = jp.getIntValue();
if (jp.nextToken() != JsonToken.VALUE_NUMBER_INT) {
throw new JsonParseException(jp, "Expected int");
}
int y = jp.getIntValue();
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw new JsonParseException(jp, "Expected array end");
}
var point = new Point();
point.x = x;
point.y = y;
return point;
}
}
public class PointJson {
public static void main(String[] args) throws Exception {
var objectMapper = new ObjectMapper();
objectMapper.registerModule(new SimpleModule() {
{
addDeserializer(Point.class, new PointDeserializer());
}
});
var json = "[1,2]";
var point = objectMapper.readValue(json, Point.class); // Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Expected array start
System.out.println(point);
}
}
Expected behavior
The first token should be an array start. It seems to be skipped.
Additional context
No response
This should perhaps be documented better, but the contract for custom deserializer is that the CURRENT token JsonParser
points to is the first token. So instead of starting with nextToken()
, your deserializer needs to start with currentToken()
, and only use nextToken()
for additional content.
Hope this helps.
Thanks, this solved my confusion!!!