我有一个基于 json 的 REST Web 服务,使用以下方法实现: 使用 Jackson 的 Jetty、Jersey、Jersey-JSON。
我的一个方法接收一个 Person 实例,它有一个 List
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 deserialization - with contained ArrayList<T>
和
How can I customize serialization of a list of JAXB objects to JSON?
这是指最后一个答案:
Jersey client can not deserializable json services - exception(can not deserialize instance)
Jaxb json missing brackets for one element array
但这些都不能解决问题。
提前致谢!
最佳答案
经过漫长的一天,又是一天......在阅读了大量的维基和常见问题解答之后,它终于成功了。
我做了什么:
- 使用 jackson
- 强制使用 Jackson 供应商
- 定义自定义反序列化器
- 激活 ACCEPT_SINGLE_VALUE_AS_ARRAY 标志
- 修复依赖关系
故事:
我使用的 Jersey 1.13 默认使用(我相信)jaxb。
我将其更改为使用 Jackson
<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
这让我的 Jersey 使用了 jackson ,但问题仍然存在; jackson 还不能反序列化数组。
我强制使用Jackson providers:
<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;
}
}
为了做到这一点:
做了所有这些之后它仍然没有工作......
经过一段时间的搜索,我发现:
讨论依赖性问题..
这暴露了我的问题,Jersey v1.13 随 Jackson v1.9.2 我需要 Jackson 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>
引用:
注意:此更改移除了 Jersey 使用 Jaxb 或 jettison 的能力。
题外话,某些人可能会感兴趣:
Configure Jersey/Jackson to NOT use @XmlElement field annotation for JSON field naming
关于java - Jersey:无法从 String 中反序列化 ArrayList 的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14319573/