【问题标题】:Deserializing unrecognized json data into a Map JacksonJson将无法识别的 json 数据反序列化为 Map JacksonJson
【发布时间】:2012-01-02 09:17:42
【问题描述】:

我有一个示例类

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_ 开头的任何字段推送到 Map 自定义中?

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

【问题讨论】:

    标签: java json spring jackson resttemplate


    【解决方案1】:

    您可能只想使用@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);
      }
    }
    

    【讨论】:

    • 解决方案非常完美。感谢您的反馈
    【解决方案2】:

    这是可能的,但我能想到的唯一方法远非“干净和完美”。 作为最后的措施,我建议在使用 Jackson 文档之前仔细阅读它

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多