Json 泽西岛(jackson)地图字段序列化

Json 泽西岛(jackson)地图字段序列化,json,jaxb,jersey,jackson,Json,Jaxb,Jersey,Jackson,我有一个简单的jersey web服务,我想使用/生成包含地图字段的对象,比如 @XmlElement private Map<String,String> properties; 属性字段反序列化为空,没有错误。同样的JSON进出GSON没有问题,短期内我通过让GSON生成字符串并使用GSON对JSON进行序列化/反序列化来解决这个问题 有什么想法吗? 谢谢。一个选择是使用带注释的类。例如,一个用户可能由以下数据表示 import javax.xml.bind.annotatio

我有一个简单的jersey web服务,我想使用/生成包含地图字段的对象,比如

@XmlElement
private Map<String,String> properties;
属性字段反序列化为空,没有错误。同样的JSON进出GSON没有问题,短期内我通过让GSON生成字符串并使用GSON对JSON进行序列化/反序列化来解决这个问题

有什么想法吗?
谢谢。

一个选择是使用带注释的类。例如,一个用户可能由以下数据表示

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "user")
public class User { 
    private int uid;
    public int user_id;
    public String user_name;
    public String email;
    public URI image_url;
    public List<User> friends;
    public boolean admin;

    public User() {
        ...
    }
    public User(final int userid) {
        // Find user by id
    }
}

Jersey使用JAXB进行序列化。JAXB无法序列化映射,因为Java类型映射没有XML类型。此外,Map是一个接口,JAXB不喜欢接口。 如果您使用JAXBJackson桥进行封送,您将遇到问题

您需要创建一个如下所示的适配器,并使用

@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;
    }


  }

}
@XmlJavaTypeAdapter(MapAdapter.class)
私人地图财产;
@XmlSeeAllow({Adapter.class,MapElement.class})
公共类MapAdapter扩展了XmlAdapter{
@凌驾
公共适配器封送处理(映射)引发异常{
if(map==null)
返回null;
返回新适配器(map);
}
@凌驾
公共映射解组器(适配器)引发异常{
抛出新的UnsupportedOperationException(“不支持将列表解组到映射中”);
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name=“Adapter”,namespace=“MapAdapter”)
公共静态最终类适配器{
清单项目;
公共适配器(){}
公共适配器(映射){
item=newarraylist(map.size());
对于(Map.Entry:Map.entrySet()){
添加(新地图元素(条目));
}      
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name=“MapElement”,namespace=“MapAdapter”)
公共静态最终类MapElement{
@XmlAnyElement
私钥;
@XmlAnyElement
私人价值;
公共MapElement(){};
公共映射元素(K键,V值){
this.key=key;
这个值=值;
}
公共MapElement(Map.Entry){
key=entry.getKey();
value=entry.getValue();
}
公共K getKey(){
返回键;
}
公共无效设置密钥(K密钥){
this.key=key;
}
public V getValue(){
返回值;
}
公共无效设置值(V值){
这个值=值;
}
}
}

听说过JSON吗?您刚刚重新创建了它;)虽然你给它贴上了这样的标签。。。到底是什么问题?Java有很多JSON解析器,请不要侮辱别人。这不会让你走得很远。@BrianRoach如果你仔细阅读了这个问题,Jeffrey提到了术语“GSON”。Gson是一个Java库,可用于将Java对象转换为其JSON表示形式。所以这里的问题比从谷歌搜索中取出JSON解析器并使用它要复杂一些。@VikramBodicherla-看到上面写着“4月10日编辑”的东西了吗。。。也许你将来可能想在滔滔不绝之前关注这类事情。点击它会告诉你当我对这个问题发表评论时这个问题是什么样子的。@BrianRoach对不起我的错。但你为什么这么神经质,伙计!带着所有的讽刺!!谢谢,但问题是关于如何正确传递带有贴图字段的对象。jersey+jackson不想将其序列化/反序列化。我将尝试编辑问题以使其更清楚。你是说传入对象类型?泽西+杰克逊不能处理这个问题。您需要定义对象中的值。嗯。。。不可以。要序列化/反序列化的java对象只有一个映射字段。您确定要用值填充映射吗?如果没有值,那么它将被序列化为空对象。映射以json的形式出现。我替换了jackson w/GSON,它工作正常,所以我认为它是有效的。我尝试以各种方式排列json的格式,但仍然得到null。不管怎样,如果json无效,jackson应该告诉我。谢谢。我现在已经开始使用GSON,但这是一个很好的信息。
@GET
@Path("/{userid}")
@Produces("application/json", "application/xml")
    public User showUser(@PathParam("userid") final int userid) {
        return new User(userid);
}
@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;
    }


  }

}