Jersey:无法从String中反序列化ArrayList的实例

lpi*_*.eu 13 java rest jax-rs jersey jackson

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

我的一个方法接收一个Person实例,它有一个List <String>类型的字段.即:

Public class Person {
    List<String> names;
}
Run Code Online (Sandbox Code Playgroud)

如果我用一系列名字来称呼它,一切正常!例如:

{ "names" : [ "Jhon", "Doe" ] }
Run Code Online (Sandbox Code Playgroud)

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

{ "names" : "Jhon" } 
Run Code Online (Sandbox Code Playgroud)

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

Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token
Run Code Online (Sandbox Code Playgroud)

题:

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

-

我已经读过:

杰克逊反序列化 - 包含ArrayList <T>

如何自定义JAXB对象列表到JSON的序列化?

这是指最后一个答案:

Jersey客户端无法反序列化json服务 - 异常(无法反序列化实例)

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

但这些都没有解决问题.

先感谢您!

lpi*_*.eu 12

经过漫长的一天,另一个......在阅读了很多维基和常见问题后,它终于奏效了.

我做了什么:

  1. 使用杰克逊
  2. 强制Jackson提供者使用
  3. 定义自定义反序列化器
  4. 激活ACCEPT_SINGLE_VALUE_AS_ARRAY标志
  5. 修复依赖项

故事:

我正在使用Jersey 1.13默认使用(我相信)jaxb.

我改变它使用杰克逊

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>
Run Code Online (Sandbox Code Playgroud)

如下所述:

/sf/answers/972703791/

这让我的球衣使用杰克逊,但问题仍然存在; 杰克逊还不能对阵列进行反序列化.

我强迫使用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>
Run Code Online (Sandbox Code Playgroud)

/sf/answers/220025011/

是一个必要的步骤,但还不够.必须激活ACCEPT_SINGLE_VALUE_AS_ARRAY标志.

ObjectMapper objectMapper;
objectMapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
Run Code Online (Sandbox Code Playgroud)

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

public class MyResolver implements ContextResolver<ObjectMapper> {

@Override
    public ObjectMapper getContext(final Class<?> objectType) {
        ...            
        return objectMapper;
    }
}
Run Code Online (Sandbox Code Playgroud)

为了做到这一点:

定制-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>
Run Code Online (Sandbox Code Playgroud)

并直接声明依赖:

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

参考:

杰克逊JAXRS JSON的提供商

注意:此更改会删除Jersey使用Jaxb或jettison的能力.

关闭主题,可能对某人有趣:

将Jersey/Jackson配置为不使用@XmlElement字段注释进行JSON字段命名


ste*_*n35 5

您可以使用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;
}
Run Code Online (Sandbox Code Playgroud)