有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Jersey:无法反序列化字符串外的ArrayList实例

我使用以下方法实现了一个基于json的REST Web服务: 杰蒂,泽西,泽西,杰克逊

我的一个方法接收一个Person实例,该实例的字段类型为List<;字符串>;。 i、 e:

Public class Person {
    List<String> names;
}

如果我用一组名字来称呼它,一切正常!e、 g:

{ "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

但这些都不能解决问题

提前谢谢你


共 (5) 个答案

  1. # 1 楼答案

    通过将@JsonSerialize添加到类中,它对我起了作用

    @JsonSerialize
    Public class Person {
        List<String> names;
    }
    
  2. # 2 楼答案

    {a1}的示例5.10和5.11解释了您的确切问题。您可以将JSON生成器配置为强制单个项目列表使用数组,如下所示: JSONConfiguration.mapped().arrays("names").build()

  3. # 3 楼答案

    {"results": {"place": {"lang": "en-US","woeid": "2168606"}}}
    

    &

    {"results": {"place": [{"lang": "en-US","woeid": "2168606"}, {"lang": "en-US","woeid": "2168606"}]}}
    

    这种类型怎么办。。。使用yahoo place api时

  4. # 4 楼答案

    经过漫长的一天,又一天。。。在阅读了大量的维基和常见问题后,它终于起作用了

    我所做的:

    1. 使用杰克逊
    2. 强制使用
    3. 定义自定义反序列化程序
    4. 激活接受\u单个\u值\u作为\u数组标志
    5. 修复依赖项

    故事:

    我使用的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

    这使得我的球衣使用了杰克逊,但问题依然存在;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

    这是必要的一步,但还不够。有必要激活接受单个值作为数组标志

    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;
        }
    }
    

    为此:

    Customizing-ObjectMapper

    在做了所有这些之后,它仍然不起作用

    再搜索一段时间后,我发现:

    Jackson 2.0 with Jersey 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

    注意:此更改取消了Jersey使用Jaxb或抛弃的功能

    离题,可能会引起某人的兴趣:

    Configure Jersey/Jackson to NOT use @XmlElement field annotation for JSON field naming

  5. # 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;
    }