java.util.Map / HashMap JAXB to JSON with Jackson - com.fasterxml.jackson.databind.JsonMappingException:无法缩小内容类型

时间:2013-11-18 15:15:47

标签: json map jaxb jackson

尝试使用带有JAXB注释的json消息中的Map / HashMap属性反序列化类时我得到了

com.fasterxml.jackson.databind.JsonMappingException: Failed to narrow content type [map type; class java.util.HashMap, [simple type, class java.lang.String] -> [simple type, class blog.map.generated.Address]] with content-type annotation (blog.map.generated.Customer$AddressMap): Class blog.map.generated.Customer$AddressMap is not assignable to blog.map.generated.Address

我的json消息:

{"addressMap":{"shipping":{"street":"2 B Road"},"billing":{"street":"1 A Street"}}}

我的JAXB注释类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customer", propOrder = {
"addressMap"
})
public class Customer {

@XmlElement(required = true, type = Customer.AddressMap.class)
protected HashMap<String, Address> addressMap;
public HashMap<String, Address> getAddressMap() {
    return addressMap;
}

public void setAddressMap(HashMap<String, Address> value) {
    this.addressMap = value;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "entry"
})
public static class AddressMap {

    protected List<Customer.AddressMap.Entry> entry;

    public List<Customer.AddressMap.Entry> getEntry() {
        if (entry == null) {
            entry = new ArrayList<Customer.AddressMap.Entry>();
        }
        return this.entry;
    }


    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "key",
        "value"
    })
    public static class Entry {

        protected java.lang.String key;
        protected blog.map.generated.Address value;

        public java.lang.String getKey() {
            return key;
        }

        public void setKey(java.lang.String value) {
            this.key = value;
        }

        public blog.map.generated.Address getValue() {
            return value;
        }

        public void setValue(blog.map.generated.Address value) {
            this.value = value;
        }

    }

}
}

我尝试通过为HashMap属性创建自定义XmlAdapter来避免此问题,如下所示:

public class MapAdapter extends XmlAdapter<MapAdapter.AdaptedMap, Map<String, Address>> {

public static class AdaptedMap {
    public List<Entry> entry = new ArrayList<Entry>();
}
public static class Entry {
    public String key;
    public Address value;
}

@Override
public Map<String, Address> unmarshal(AdaptedMap adaptedMap) throws Exception {
    Map<String, Address> map = new HashMap<String, Address>();
    for(Entry entry : adaptedMap.entry) {
        map.put(entry.key, entry.value);
    }
    return map;
}

@Override
public AdaptedMap marshal(Map<String, Address> map) throws Exception {
    AdaptedMap adaptedMap = new AdaptedMap();
    for(Map.Entry<String, Address> mapEntry : map.entrySet()) {
        Entry entry = new Entry();
        entry.key = mapEntry.getKey();
        entry.value = mapEntry.getValue();
        adaptedMap.entry.add(entry);
    }
    return adaptedMap;
}
}

那可行但是创建了不同于我需要反序列化的消息:

{"addressMap":{"entry":[{"key":"shipping","value":{"street":"2 B Road"}},{"key":"billing","value":{"street":"1 A Street"}}]}}

在转换为键值对列表时,这有点合乎逻辑。

当我删除“地图 - &gt;键值对转换列表”而不是IT WORKS!

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customer", propOrder = {
"addressMap"
 })
public class Customer {

@XmlElement(required = true)
protected HashMap<String, Address> addressMap;


public HashMap<String, Address> getAddressMap() {
    return addressMap;
}

public void setAddressMap(HashMap<String, Address> value) {
    this.addressMap = value;
}

}

有人知道如何使用Jackson 2.2.2和JAXB来解决这个问题吗?或者如何强制XJC不生成Map-&gt; KV对转换列表?

由于

0 个答案:

没有答案