简体   繁体   中英

Jackson JSON Array Value Deserialization

I am trying to de-serialize this JSON object using Jackson 2.8 as part of Retrofit response. Here is the JSON response I get from the server.

{
 "id":"8938209912"
 "version":"1.1"
 "cars":{  
    "mercedes":[  
       {  
          "property":"color"
       },
       {  
          "property":"price"
       },
       {  
          "property":"location"
       }
    ],
    "tesla":[  
       {  
          "property":"environment"
       }
    ]
  }
}

Based on the query, the cars above may have one or more models returned. I cannot create a class each for each model as these get created/removed arbitrarily. For each model of the car (say tesla ), there may be one or more property key-value pairs.

I am new to Jackson . I have been looking at several examples and looks like a custom @JsonDeserialize is the best way to go. So, I created Root class and Cars class like this:

 // In file Root.java
 public class Root {
    @JsonProperty("id")
    private String id = null;


    @JsonProperty("version")
    private String version = null;

    @JsonProperty("cars")
    private Cars cars = null;
 }

 // In file Cars.java
 public class Cars {

    public Cars(){} 

    @JsonDeserialize(using = CarDeserializer.class)
    private Map<String, List<Property>> properties; 

    public Map<String, List<Property>> getProperties() {
        return properties;
    }

    public void setProperties(Map<String, List<Property>> properties) {
        this.properties = properties;
    }   
 }

 // Property.java
 public class Property {

   @JsonProperty("property")
   private String property;
 }

My de-serializer is below. However, even though the empty constructor gets called, the parse method itself is not called at all!

     // CarDeserializer.class
     public class RelationshipDeserializer extends StdDeserializer<Map<String, List<Action>>>{

         protected RelationshipDeserializer(){
            super(Class.class);
         }  

        @Override
        public Map<String, List<Action>> deserialize(JsonParser parser, DeserializationContext ctx)
        throws IOException, JsonProcessingException 
        {
             // This method never gets invoked.
        }
     }

My questions:

  1. Is this the right approach in the first place?
  2. Why do you think the execution never gets to the deserialize() ? (I checked, the cars object is present in JSON.
  3. Are there better approaches to parse this JSON using Jackson ?

The "properties" deserializer is never called because that does not match anything in that JSON. The field name in the JSON is "property" and it does not match Map<String, List<Property>> . It looks like it would be closer to List<Property>

Do you control the in coming JSON? It would be better for the car name/type to be in its own field rather than the name of the object. Then you can use a generic object. What you have now is going to break. Any time they add a new name/type and you do not have a matching object for it.

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