1

我有一个示例类

public class Category {
private String id ;
    private String name ;

private String description ;

private String image ;

private String thumbnail ;
 private Map<String, String> custom ;
}

我有来自服务器的以下格式的响应,但例如,让我们说这是在文件 cat.json 中

{"id":"mens","name":"Mens","c__showInMenu":true,"c__enableCompare":false}

   1 ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
   2 Category cat= mapper.readValue(new File("cat.json"), Category.class);

这对于字段 id、name 等非常有效。如何编写自定义反序列化器,以便将 json 中以开头的任何字段c_推送到自定义地图中?

我对 Jackson 很陌生,正在使用 Springs Rest Template 并将其配置为使用 org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.

4

2 回答 2

2

您可能只想简单地使用@JsonAnySetter.

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    Category category = mapper.readValue(new File("cat.json"), Category.class);
    System.out.println(category);
    // output:
    // Category: id=mens, name=Mens, description=null, image=null, thumbnail=null, custom={c__showInMenu=true, c__enableCompare=false}
  }
}

class Category
{
  private String id;
  private String name;
  private String description;
  private String image;
  private String thumbnail;
  private Map<String, String> custom;

  @JsonAnySetter
  void addSomething(String name, String value)
  {
    if (custom == null) custom = new HashMap();
    custom.put(name, value);
  }

  @Override
  public String toString()
  {
    return String.format("Category: id=%s, name=%s, description=%s, image=%s, thumbnail=%s, custom=%s", 
        id, name, description, image, thumbnail, custom);
  }
}
于 2012-01-03T05:10:16.620 回答
0

这是可能的,但我能想到的唯一方法远非“干净和完美”。 作为最后的措施,我建议在使用 Jackson 文档之前对其进行挖掘

您可以做的是创建一个带有 map 字段的类,该类将包含序列化对象的所有属性,如下所示:

public class CustomObject {
    private Map<String,Object> map;
}

这样杰克逊可以解析这样的对象:

{ map : {"id":"mens","name":"Mens","c__showInMenu":true,"c__enableCompare":false}}

现在,您仍然有不想要的“地图”包装器,这会弄乱反序列化。一种解决方案是用“{ map :”和结束标记“}”包围传入的 JSON 内容。

这样,Jackson 将正确映射您的对象,您将拥有所有属性的映射,您可以对其进行迭代,获取检查类型instanceof并检索所有数据。

再一次,这可能不是最好的方法,您应该首先尝试更清洁的解决方案。我不是杰克逊方面的专家,所以我无法为您指明更好的方向。

于 2012-01-02T09:35:57.343 回答