泽西岛:无法从字符串中反序列化 ArrayList 的实例

2022-09-04 08:32:50

我有一个基于json的REST Web服务,使用:Jetty,Jersey,Jersey-JSON使用Jackson。

我的一个方法接收一个 Person 实例,该实例的字段类型为 List<String>。即:

Public class Person {
    List<String> names;
}

如果我用一系列名称来称呼它,一切都可以正常工作!例如:

{ "names" : [ "Jhon", "Doe" ] }

但是,如果此人只有一个名字,我的客户端会创建一个值元素,例如:

{ "names" : "Jhon" } 

当我尝试使用单个值调用服务时,我得到一个异常:

Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token

问题:

我应该如何创建/配置我的Web服务,以便在数组字段作为单个元素发送给我时能够反序列化它们。

--

我已经读过:

Jackson 反序列化 - 包含 ArrayList<T>

如何将 JAXB 对象列表的序列化定制为 JSON?

这个指的是最后一个答案:

泽西客户端无法反序列化 json 服务 - 异常(不能反序列化实例)

Jaxb json 缺少一个元素数组的括号

但这些都没有解决问题。

提前感谢您!


答案 1

经过漫长的一天,又一个...在阅读了许多wiki和常见问题解答之后,它终于可以工作了。

我做了什么:

  1. 使用杰克逊
  2. 强制杰克逊提供程序的使用
  3. 定义自定义反序列化程序
  4. 激活ACCEPT_SINGLE_VALUE_AS_ARRAY标志
  5. 修复依赖关系

故事:

我使用的是泽西岛1.13,默认情况下使用(我活着)jaxb。

我把它改成使用杰克逊

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

如以下所述:

https://stackoverflow.com/a/13895768/660990

这使我的球衣使用杰克逊,但问题仍然存在;jackson 还不能反序列化数组。

我强制使用 Jackson 提供程序

<init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>
        your.project.packages;
        org.codehaus.jackson.jaxrs</param-value>
</init-param>

https://stackoverflow.com/a/3143214/660990

这是一个需要的步骤,但还不够。有必要激活ACCEPT_SINGLE_VALUE_AS_ARRAY标志。

ObjectMapper objectMapper;
objectMapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

我需要定义自定义反序列化程序

public class MyResolver implements ContextResolver<ObjectMapper> {

@Override
    public ObjectMapper getContext(final Class<?> objectType) {
        ...            
        return objectMapper;
    }
}

为了做到这一点:

自定义对象映射器

在完成所有这些操作后,它仍然不起作用...

经过一番搜索,我发现:

杰克逊 2.0 与泽西 1.12

这讨论了依赖性问题

这揭示了我的问题, 泽西岛 v1.13杰克逊 v1.9.2 我需要杰克逊 v2.0

我删除了 jersey-json 的依赖项,因为它包含 jackson 1.9.2:

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
</dependency>

并直接声明了以下各项的依赖关系:

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>

参考:

jackson-jaxrs-json-provider

注意:此更改删除了泽西岛使用 Jaxb 或抛弃的能力。

题外话,可能对某人感兴趣:

将泽西/杰克逊配置为不使用@XmlElement字段注释进行 JSON 字段命名


答案 2

您可以使用JsonFormat注释在类,字段或方法级别使用注释来执行此操作

@JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
protected List<String> list;

public List<String> getList() {
    return list;
}

public void setList(List<String> list) {
    this.list = list;
}