泽西(+杰克逊)地图场序列化 [英] jersey (+ jackson) map field serialization

查看:119
本文介绍了泽西(+杰克逊)地图场序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的球衣网络服务,我想使用/生成包含地图字段的对象,例如

i have a simple jersey web service and i'd like to consume / produce objects that contain map fields, like

@XmlElement
private Map<String,String> properties;

如果此字符串进入网络服务,

if this string goes into the web service,

{ properties: { key1: val1, key2: val2 )}

将属性字段反序列化为null,没有错误。相同的JSON进出GSON没有任何问题,并且在短期内我通过让jersey消耗产生字符串并使用GSON序列化/反序列化JSON来解决这个问题。

the properties field is deserialized as null with no errors. the same JSON goes in and out of GSON no problems, and in the short term i solved this by having jersey consume produce strings and using GSON to serialize / deserialize the JSON.

任何想法?
谢谢。

any ideas? thanks.

推荐答案

Jersey使用JAXB进行序列化。 JAXB无法序列化Map,因为Java类型Map没有XML类型。此外,Map是一个接口,JAXB不喜欢接口。
如果你使用JAXBJackson桥来编组,你就会遇到问题。

Jersey uses JAXB for serialization. JAXB can not serialize a Map as there is no XML type for Java type Map. Also, Map is an interface and JAXB does not like interfaces. If you are using JAXBJackson bridge to marshal, you will run into issue.

你需要创建一个如下所示的适配器并使用<注释你的Map属性/ p>

You will need to create an adapter like below and annotate your Map property with

@XmlJavaTypeAdapter(MapAdapter.class)
private Map<String,String> properties;

@XmlSeeAlso({ Adapter.class, MapElement.class })
public class MapAdapter<K,V> extends XmlAdapter<Adapter<K,V>, Map<K,V>>{


  @Override
  public Adapter<K,V> marshal(Map<K,V> map) throws Exception {

    if ( map == null )
      return null;

    return new Adapter<K,V>(map);
  }


  @Override
  public Map<K,V> unmarshal(Adapter<K,V> adapter) throws Exception {
    throw new UnsupportedOperationException("Unmarshalling a list into a map is not supported");
  }

  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name="Adapter", namespace="MapAdapter")
  public static final class Adapter<K,V>{

    List<MapElement<K,V>> item;

    public Adapter(){}

    public Adapter(Map<K,V> map){
      item = new ArrayList<MapElement<K,V>>(map.size());
      for (Map.Entry<K, V> entry : map.entrySet()) {
        item.add(new MapElement<K,V>(entry));
      }      
    }
  }

  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name="MapElement", namespace="MapAdapter")
  public static final class MapElement<K,V>{

    @XmlAnyElement
    private K key;

    @XmlAnyElement
    private V value; 

    public MapElement(){};

    public MapElement(K key, V value){
      this.key = key;
      this.value = value;
    }

    public MapElement(Map.Entry<K, V> entry){
      key = entry.getKey();
      value = entry.getValue();
    }

    public K getKey() {
      return key;
    }

    public void setKey(K key) {
      this.key = key;
    }

    public V getValue() {
      return value;
    }

    public void setValue(V value) {
      this.value = value;
    }


  }

}

这篇关于泽西(+杰克逊)地图场序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆