将无法识别的json数据反序列化为Map JacksonJson

时间:2012-01-02 09:17:42

标签: java json spring jackson resttemplate

我有一个示例类

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,名称等完全正常。 如何编写自定义反序列化器,以便将以c_开头的json中的任何字段推送到Map自定义中?

我对杰克逊很新,并且正在使用弹簧模板并将其配置为使用 org.springframework.http.converter.json.MappingJacksonHttpMessageConverter

2 个答案:

答案 0 :(得分: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);
  }
}

答案 1 :(得分:0)

这是可能的,但我能想到的唯一方法远不是“干净和完美”。 我建议在使用之前深入了解Jackson文档,作为最后一项措施

你可以做的是创建一个带有map字段的类,它将保存序列化对象的所有属性,如下所示:

public class CustomObject {
    private Map<String,Object> map;
}
杰克逊可以解析这些对象:

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

现在,你仍然有不受欢迎的“map”包装器,这会破坏反序列化。一种解决方案可以是使用“{map:”和结束标记“}”包围传入的JSON内容。

杰克逊将正确映射您的对象,您将拥有所有属性的地图,您可以迭代它,通过instanceof获取检查类型并检索所有数据。

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