简体   繁体   中英

How to use regular JSON interpretation inside of a Jackson custom JSON deserializer

I am writing a custom deserializer and not sure how to best handle the following case:

I am deserializing something that looks like this:

{
  "someProp": {
    "name": "some string"
    "value": ****** can be anything here, including string, number, object, etc. ******
  }
}

The object I am mapping this to has this:

public class ObjectToMapTo {
    String name;
    Object value;
}

In my code, I have the JsonNode that represents the someProp field. I can obviously extract the JsonNode of the name and easily convert it to String with JsonNode.asText() .

However, how do I deal with the value ? JsonNode does NOT have a method for asObject() . Surprisingly, it only has isObject() . Do I have to go through a switch statement to figure out what type of of a thing it is just so I can call the correct method like asLong() or asText() ?

But even if I do the switch statement, what if the nodeType is Object . Then what? How do I get that JsonNode to just be a regular Java Map like it would regularly if I were to use the ObjectMapper without a custom deserializer?

I am afraid you have to do some custom deserializing and switching/iffing here.

JsonNode does NOT have a method for asObject(). Surprisingly, it only has isObject().

Yes. It is not a problem to determine if the value is an object since object nodes start with { . But to what specific class instance it can be constructed is impossible to guess. That should not be surprising.

what if the nodeType is Object. Then what? How do I get whatever is specified for value in JSON

If there was a field - say type - that tells the type you could do it easily in your custom deserializer. So if you have power to add it then you could give there the whole class name to instantiate to in your deserializer.

Otherwise I think the best you can do would be to instantiate arbitrary object as an instance of a Map or just as a TreeNode .

You could annotate field value for the deserialiser like (so not the parent):

@Getter @Setter
public class ObjectToMapTo {
    private String name;
    @JsonDeserialize(using =  MyDeserializer.class)
    private Object value;
}

In your deserializer after you have checked that it is not array nor value, something like:

Object o;
TreeNode valueTreeNode = jp.readValueAsTree();
// check if array or valueNode
// but if is object
ObjectMapper om = new ObjectMapper();
o = om.treeToValue(valueTreeNode, Map.class);
return o;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM