使用“key”&amp ;;反序列化JSON映射“价值”属性不适用于杰克逊

时间:2013-12-20 10:07:04

标签: java android json serialization jackson

问题

  1. 首先,下面的序列化JSON序列化是否有意义?
  2. 如果是这样,为什么我没有收回地图?
  3. 在反序列化方面我该怎么办?
  4. Map< String,String>的JSON序列化财产(摘录):

    {
      "attributes": {
        "entry": [
          {
            "key": "operating system",
            "value": "GNU/Linux"
          },
          {
            "key": "allergies",
            "value": "weed"
          }
        ]
      }
    }
    

    用于反序列化的POJO:

    class Contact implements Comparable<Contact>, Serializable {
        @JsonProperty("attributes")
        private Map<String, String> attributes;
        ...
    }
    

    导致此异常:

    Thread-4889 An exception occurred during request network execution :Could not read JSON: Can not deserialize instance of java.lang.String out of START_ARRAY token
                at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
                at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"])
        org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of java.lang.String out of START_ARRAY token
                at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
                at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"])
                at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readInternal(MappingJackson2HttpMessageConverter.java:126)
                at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:147)
                at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:76)
                at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:484)
                at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
                at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
                at com.example.providers.Query$1.loadDataFromNetwork(Query.java:99)
                at com.octo.android.robospice.request.CachedSpiceRequest.loadDataFromNetwork(CachedSpiceRequest.java:45)
                at com.octo.android.robospice.request.RequestRunner.processRequest(RequestRunner.java:130)
                at com.octo.android.robospice.request.RequestRunner$1.run(RequestRunner.java:197)
                at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
                at java.util.concurrent.FutureTask.run(FutureTask.java:234)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
                at java.lang.Thread.run(Thread.java:841)
         Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
                at [Source: libcore.net.http.FixedLengthInputStream@43822760; line: 1, column: 17] (through reference chain: com.example.model.Contact["attributes"])
                at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
                at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:46)
                at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
                at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringMap(MapDeserializer.java:430)
                at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:312)
                at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26)
                at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:525)
                at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:106)
                at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:242)
                at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
                at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:227)
                at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.des
    

    反序列化后在调试器中检查时的属性Object:

    Deserialized Object inspected in debugger

    更改为:

    后进一步检查
    @JsonProperty("attributes")
    private Map<String, List<Map<String, String>>> attributes;
    

    attributes.entrySet() attributes.get("entry")

    依赖关系:

    • com.fasterxml.jackson.core:杰克逊 - 芯:2.3.0
    • com.fasterxml.jackson.core:杰克逊 - 数据绑定:2.3.0
    • com.fasterxml.jackson.core:杰克逊 - 注解:2.3.0

1 个答案:

答案 0 :(得分:8)

如果我们将Map转换为json:

    Map<String, String> map = new HashMap<String, String>();
    map.put("operating system", "GNU/Linux");
    map.put("allergies", "weed");

输出将是:

{"operating system":"GNU/Linux","allergies":"weed"}

我们可以看到没有key/value

解决方案

<强> WrapperObject

@JsonIgnoreProperties(ignoreUnknown = true)
public class WrapperObject { // we can give any name to class, its only external {}    

    private Attributes attributes;

    public WrapperObject() {}

    public Attributes getAttributes() {
        return attributes;
    }    
}

<强>属性

@JsonIgnoreProperties(ignoreUnknown = true)  
public class Attributes {

    public Attributes() {}

    private ArrayList<Entry> entry;  

    public ArrayList<Entry> getEntry() {
        return entry;
    }    
}

<强>条目

@JsonIgnoreProperties(ignoreUnknown = true)    
public  class Entry {

    private String key;
    private String value;


    public Entry() {}


    public String getKey() {
        return key;
    }


    public String getValue() {
        return value;
    }
}

<强>启动

public static void main(String[] args) throws JsonParseException, JsonMappingException,     IOException {
    String str = "{" + 
            "  \"attributes\": {" + 
            "    \"entry\": [" + 
            "      {" + 
            "        \"key\": \"operating system\"," + 
            "        \"value\": \"GNU/Linux\"" + 
            "      }," + 
            "      {" + 
            "        \"key\": \"allergies\"," + 
            "        \"value\": \"weed\"" + 
            "      }" + 
            "    ]" + 
            "  }" + 
            "}";



    ObjectMapper mapper = new ObjectMapper();
    WrapperObject mj = mapper.readValue(str, WrapperObject.class);

    if(mj == null){
        System.err.println("null");
    }
    // dummy check
    System.out.println(mj.getAttributes().getEntry().get(0).getKey());
}

输出:

operating system