-
Notifications
You must be signed in to change notification settings - Fork 543
Description
Description:
Codegen incorrectly deserializes Maps because of double jsonReader.readFieldName() call.
For example, if your DTO has "elements" Map field, the generated code in ..._FASTJSONReader looks like this (the relevant piece):
...
String elements_key = jsonReader.readFieldName();
if (jsonReader.isReference()) {
String ref = jsonReader.readReference();
jsonReader.addResolveTask(elements, elements_key, JSONPath.of(ref));
} else {
elements.put(jsonReader.readFieldName(), (MyDto)this.itemReader0.readObject(jsonReader, MyDto.class, "elements", features));
}
...
So the flow is:
String elements_key = jsonReader.readFieldName();elements.put(jsonReader.readFieldName(), ...
causing the reader to advance multiple times on the field name hence breaking the reader cursor basically.
Seems like the cause is here:
Line 3042 in 0e7ef92
| exec(method(fieldValueVar, "put", mapEntryKeyExpr, mapEntryValueExpr)) |
Instead of mapEntryKeyExpr it should use ident(mapKey) to fix it, it seems.
It worked fine, when I copy pasted generated code with the fix applied on top, so it's likely the cause.
Environment:
- OS: Linux
- JDK: Openjdk-21.0.5+11
- Fastjson2 and codegen: 2.0.59
- Quarkus: 3.28.4
Reproduction:
- Use a
Mapfield in your DTO class with codegen, for example:
@JSONCompiled
@JSONType
public class MyDto {
...
public Map<String, MyOtherDto> elements;
...- Build the project.
- Send some corresponding valid json.
- Parse json:
MyDto dto = JSON.parseObject(json, MyDto.class);
Actual
Instead of real valid "elements" items, your MyDto will have only a single element with "null" key (though I suppose you might see a different result, because an incorrectly advanced parser might yield different results depending on input data, etc).
The real json had something like this instead:
...
"elements": {
...
"7": {
"format": "mmddhhnnss",
"id": 7,
"type": "datetime",
"value": "0302054257"
},
...
}
...
Expected
Map gets parsed correctly, and then written back to json string also correctly.