无法从 VALUE_STRING 中反序列化 java.util.ArrayList 的实例 [英] Can not deserialize instance of java.util.ArrayList out of VALUE_STRING

查看:100
本文介绍了无法从 VALUE_STRING 中反序列化 java.util.ArrayList 的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 Jersey 构建并部署在 AppEngine 中的 REST 服务.REST 服务实现了使用 application/json 媒体类型的动词 PUT.数据绑定由 Jackson 执行.

I have a REST service built with Jersey and deployed in the AppEngine. The REST service implements the verb PUT that consumes an application/json media type. The data binding is performed by Jackson.

动词使用以 JSON 表示的企业-部门关系

The verb consumes an enterprise-departments relation represented in JSON as

{"name":"myEnterprise", "departments":["HR","IT","SC"]}

在客户端,我使用 gson 将 JSON 表示转换为 java 对象.然后,我将对象传递给我的 REST 服务,它运行良好.

On the client side, I use gson to convert the JSON representation into a java object. Then, I pass the object to my REST service and it works fine.

问题:

当我的 JSON 表示在集合中只有一项时

When my JSON representation has only one item in the collection

{"name":"myEnterprise", "departments":["HR"]}

服务无法反序列化对象.

the service cannot deserialize the object.

ATTENTION: /enterprise/enterprise: org.codehaus.jackson.map.JsonMappingException: 
Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token at 
[Source: org.mortbay.jetty.HttpParser$Input@5a9c5842; line: 1, column: 2

据其他用户报告,解决方案是添加标志ACCEPT_SINGLE_VALUE_AS_ARRAY(例如,Jersey:不能从字符串中反序列化 ArrayList 的实例).尽管如此,我并没有控制 ObjectMapper 因为在服务端它是由 Jackson 透明地制作的.

As reported by other users, the solution is to add the flag ACCEPT_SINGLE_VALUE_AS_ARRAY (e.g., Jersey: Can not deserialize instance of ArrayList out of String). Nevertheless, I am not controlling an ObjectMapper because in the service side it is transparently made by Jackson.

问题:

有没有办法在服务端配置ObjectMapper来启用ACCEPT_SINGLE_VALUE_AS_ARRAY?注释?web.xml?

Is there a way to configure the ObjectMapper on the service side to enable ACCEPT_SINGLE_VALUE_AS_ARRAY? annotations? web.xml?

代码详情

Java 对象:

@XmlRootElement
public class Enterprise {
    private String name;
    private List<String> departments;

    public Enterprise() {}

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<String> getDepartments() {
        return departments;
    }
    public void setDepartments(List<String> departments) {
        this.departments = departments;
    }
}

REST 服务端:

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/enterprise") 
    public Response putEnterprise(Enterprise enterprise,
            @Context HttpServletRequest req){
         ...
    }

客户端:

...
String jsonString = "{\"name\":\"myEnterprise\", \"departments\":[\"HR\"]}";
Enterprise enterprise = gson.fromJson(jsonString, Enterprise.class);
System.out.println(gson.toJson(enterprise));
response = webResource              
           .type(MediaType.APPLICATION_JSON)
           .put(ClientResponse.class,enterprise);
if (response.getStatus() >= 400) {
        throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
...

推荐答案

这是我的老问题的解决方案:

This is the solution for my old question:

我实现了自己的 ContextResolver 以启用 DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY 功能.

I implemented my own ContextResolver in order to enable the DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY feature.

package org.lig.hadas.services.mapper;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;

@Produces(MediaType.APPLICATION_JSON)
@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper>
{
   ObjectMapper mapper;

   public ObjectMapperProvider(){
       mapper = new ObjectMapper();
       mapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
   }
   @Override
   public ObjectMapper getContext(Class<?> type) {
       return mapper;
   }
}

web.xml 中,我将我的包注册到 servlet 定义中...

And in the web.xml I registered my package into the servlet definition...

<servlet>
    <servlet-name>...</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>...;org.lig.hadas.services.mapper</param-value>        
    </init-param>
    ...
</servlet>

...剩下的一切都由球衣/杰克逊透明地完成.

... all the rest is transparently done by jersey/jackson.

这篇关于无法从 VALUE_STRING 中反序列化 java.util.ArrayList 的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆