JsonParser should provide a method that returns current target value type
See original GitHub issueIs your feature request related to a problem? Please describe. we want deserialize generic class based on target value type at customerized JsonDeserializer.
// generic class
@Data
@JsonSerialize(using = CustomSerializer.class)
@JsonDeserialize(using = CustomDeserializer.class)
public class A<U extends BaseU, V extends BaseV> {
// all U have AnnotationForU as json field key.
private U u;
// all V have AnnotationForV as json field key.
private V v;
}
@AnnotationForU(value = "NameU")
public class U extends BaseU {
...
}
@AnnotationForV(value = "NameV")
public class V extends BaseV {
...
}
// customerized serializer
public class CustomSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value instanceof A) {
final A<?, ?> a = (A<?, ?>) value;
gen.writeStartObject();
// get AnnotationForU value as JSON field key of u.
gen.writeObjectField(a.u.getClass().getAnnotation(AnnotationForU.class).value(), a.u);
// get AnnotationForV value as JSON field key of v.
gen.writeObjectField(a.v.getClass().getAnnotation(AnnotationForV.class).value(), a.v);
gen.writeEndObject();
}
}
}
// customerized deserializer
public class CustomDeserializer extends JsonDeserializer<Object> {
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
// we want get current target value type from JsonParser.
JavaType toValueType = p.getToValueType();
if (toValueType instanceof TypeBase) {
// get type bindings.
TypeBindings bindings = ((TypeBase) toValueType).getBindings();
// map json field key -> generic name.
Map<String, String> boundNameMap = new HashMap<>();
// map json field key -> class.
Map<String, Class<?>> clzMap = new HashMap<>();
for (int i = 0; i < bindings.size(); i++) {
switch (bindings.getBoundName(i)) {
case "U":
String uFieldName = bindings.getBoundType(i).getRawClass().getAnnotation(AnnotationForU.class).value();
boundNameMap.put(uFieldName, "U");
clzMap.put(uFieldName, bindings.getBoundType(i).getRawClass());
break;
case "V":
String vFieldName = bindings.getBoundType(i).getRawClass().getAnnotation(AnnotationForV.class).value();
boundNameMap.put(vFieldName, "V");
clzMap.put(vFieldName, bindings.getBoundType(i).getRawClass());
break;
default:
throw new RuntimeException("unknown bound name: " + bindings.getBoundName(i));
}
}
// deserializing A
A<Object, Object> a = new A<>();
ObjectMapper om = (ObjectMapper) p.getCodec();
ObjectNode objectNode = (ObjectNode) om.readTree(p);
Iterator<Entry<String, JsonNode>> it = objectNode.fields();
while (it.hasNext()) {
Entry<String, JsonNode> entry = it.next();
Class<?> clz = clzMap.get(entry.getKey());
if (clz == null) {
throw new RuntimeException("unknown json field name: " + entry.getKey());
}
Object value = om.convertValue((ObjectNode) entry.getValue(), clz);
String boundName = boundNameMap.get(entry.getKey());
if ("U".equals(boundName)) {
a.setU(value);
} else {
a.setV(value);
}
}
return a;
}
throw new RuntimeException("unknown toValueType: " + toValueType);
}
}
Issue Analytics
- State:
- Created a year ago
- Comments:10 (5 by maintainers)
Top Results From Across the Web
JsonParser (Jodd API Documentation) - javadoc.io
Simple, developer-friendly JSON parser. It focuses on easy usage and type mappings. Uses Jodd's type converters, so it is natural companion for Jodd ......
Read more >JsonParser (Java(TM) EE 8 Specification APIs)
JsonParser provides get methods to obtain the value at the current state of the parser. For example, the following code shows how to...
Read more >Parser - Jodd JSON
JsonParser lookups for type information from the target's property: the property type and generics information. · Use map() method to map the target...
Read more >JsonParser (JSON Documentation) - Oracle Help Center
Returns a String for the name in a name/value pair, for a string value or a number value. This method should only be...
Read more >type of event.target.value should be changed to integer in react
My state has integer value that i assigned to Zero (data:0). So while updating the state using changeHandler function data becomes string.I want ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
thanks, we got it.
@zrlw It is a convenience method, not super-optimized or meant that way. But it does what it needs to.
Note, however that there is a significant optimization in that output is NOT actually written as JSON but stored in
TokenBuffer
as tokens (String
s,Number
s etc) so this is somewhat faster than actual write-then-read.The reason this is probably best we can do is that it is very little code – it uses standard serializers, deserializers, after all – trying to create optimal conversions would require doubling of much of code; essentially writing converters in addition to serializers, deserializers.