【问题标题】:How to Deserialize JSON Array?如何反序列化 JSON 数组?
【发布时间】:2012-06-21 19:29:01
【问题描述】:

我在 CXF 中使用 Jackson 来序列化/反序列化数据。不幸的是,我在配置 CXF/Jackson 来反序列化 JSON 数组时遇到了困难。非常感谢您帮助解决问题。

到目前为止,大部分 json 数据都是对象格式,即

{ "objectCollection": [ {...}, {...}, {...}... ] }

但是,有问题的 json 数据的格式为:

[ {...}, {...}, {...} ]

Web 服务端点需要一个“GroupsDto”对象(见下文) 它有一个单一的属性——一组组,即 通过 JSON 数组传输。

@PATH(...)
public Response createGroups(GroupsDto groups) {
...
}

我在 GroupsDto 集合属性中添加了如下@JsonDeserialize,但它不起作用。我继续得到:“无法从 START_ARRAY 令牌中反序列化 GroupsDto 的实例”

public class GroupsDto {

       private Collection<GroupDto> groups;

       /**
        * @return the groups
        */
       @XmlElement(name="group")
       @JsonDeserialize(contentAs=GroupDto.class)
       public Collection<GroupDto> getGroups() {
               return groups;
       }
...
}

【问题讨论】:

标签: java json cxf jax-rs jackson


【解决方案1】:

如果json数据是这样的:

[ {...}, {...}, {...} ]

你必须使用添加另一个类说'包装器':

@JsonIgnoreProperties(ignoreUnknown = true)
public class ListDto extends ArrayList<GroupDto> {

    public ListDto() {
    }
}

在脱轨时使用这个类。这种方法对我有用。

【讨论】:

    【解决方案2】:

    您只需在 setter 中指定 @JsonDeserialize(contentAs=GroupDto.class)。序列化始终在 get 反序列化始终在 set 上,或者如果您愿意,您可以在字段中同时指定两者。

    SerializeDeserialize 的文档

    代码示例:

    import java.io.IOException;
    import java.util.List;
    
    import org.codehaus.jackson.JsonGenerationException;
    import org.codehaus.jackson.map.JsonMappingException;
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.annotate.JsonDeserialize;
    
    public class JacksonDeserialize {
    
        public static class ModelClass {
    
            private String name;
    
            public ModelClass() {
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(final String name) {
                this.name = name;
            }
    
            public ModelClass(final String name) {
                super();
                this.name = name;
            }
    
            @Override
            public String toString() {
                return "ModelClass [name=" + name + "]";
            }
    
        }
    
        public static class ListModelClass {
    
            private List<ModelClass> list;
    
            @JsonDeserialize(contentAs = ModelClass.class)
            public void setList(final List<ModelClass> list) {
                this.list = list;
            }
    
            @Override
            public String toString() {
                return "ListModelClass [list=" + list + "]";
            }
    
        }
    
        public static void main(final String[] args) throws JsonGenerationException, JsonMappingException, IOException {
            ObjectMapper objectMapper = new ObjectMapper();
            System.out.println(objectMapper.readValue("{\"list\":[{\"name\":\"name1\"},{\"name\":\"name2\"}]}",
                    ListModelClass.class));
        }
    
    }
    

    【讨论】:

    • 感谢您对 getter/setter 问题的提醒。我在您的示例中注意到您正在限定 json 数组,即 "{\" list \":...} 是否可以反序列化 without 限定条件?是的,怎么做?
    • 没有限定条件,在这种情况下,魔术是由@JsonDeserialize 注释完成的。属性contentAs 表示这是一个集合,将被反序列化为ModelClass。如果您愿意,可以将属性名称从 list 更改为其他名称。名字不重要,重要的是注释。
    • 我知道具体的名字是无关紧要的,但是没有名字的情况下怎么办呢?在您的示例中,您正在阅读{"list": [...]},它具有键“列表”,但是如果没有键(名称)怎么办——即[...]
    • 啊,问题出在这里。序列化/反序列化由CXF处理,调用预定义的ObjectMapper;因此,我不能简单地将TypeReference 传递给自定义ObjectMapper,我必须依赖预定义的ObjectMapper 和注释。
    • 好的,您使用哪个库来集成两者?
    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多