【问题标题】:jersey (+ jackson) map field serializationjersey (+ jackson) 地图字段序列化
【发布时间】:2011-07-30 05:39:18
【问题描述】:

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

@XmlElement
private Map<String,String> properties;

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

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

properties 字段被反序列化为 null 且没有错误。相同的 JSON 进出 GSON 没有问题,在短期内,我通过让球衣消耗生产字符串并使用 GSON 序列化/反序列化 JSON 解决了​​这个问题。

有什么想法吗?

【问题讨论】:

  • 听说过 JSON 吗?您刚刚重新创建了它;)尽管您将其标记为这样……到底有什么问题? Java 有许多 JSON 解析器
  • 请不要侮辱他人。这不会让你走得太远。
  • @BrianRoach 如果您正确阅读了这个问题,杰弗里提到了“GSON”这个词。 Gson 是一个 Java 库,可用于将 Java 对象转换为其 JSON 表示形式。所以这里的问题比从 Google 搜索中提取 JSON 解析器并使用它要复杂一些。
  • @VikramBodicherla - 看到上面写着“4 月 10 日已编辑”的东西......也许你以后可能想在喷出之前注意这类事情。点击它会显示当我评论它时问题的样子。
  • @BrianRoach 对不起,我的错。但是你这个人为什么这么神经质!带着所有的讽刺!!

标签: json jaxb jersey jackson


【解决方案1】:

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

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

如果您在下面的代码中返回 User 对象,那么 jaxb 会自动将 List 序列化为 JSON 列表等......

@GET
@Path("/{userid}")
@Produces("application/json", "application/xml")
    public User showUser(@PathParam("userid") final int userid) {
        return new User(userid);
}

【讨论】:

  • 谢谢,但问题是如何正确传递带有地图字段的对象。 jersey + jackson 不想序列化/反序列化。我会尝试编辑问题以使其更清楚。
  • 你的意思是传入一个Object类型?泽西+杰克逊无法处理。您需要定义对象中的值。
  • 嗯……不。要序列化/反序列化的 java 对象只包含一个映射字段。
  • 您确定要使用值填充地图吗?如果没有值,则将其序列化为空对象。
  • 地图以 json 格式出现。我用 GSON 替换了杰克逊,它工作正常,所以我认为它是有效的。我尝试以各种方式排列 json 的格式,但我仍然得到空值。无论如何,如果 json 无效,jackson 应该告诉我。
【解决方案2】:

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

您将需要创建一个如下所示的适配器并使用注释您的 Map 属性

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


  }

}

【讨论】:

  • 谢谢。在这一点上我已经开始使用 GSON,但是很好的信息。
猜你喜欢
  • 2012-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
相关资源
最近更新 更多