gpt4 book ai didi

java - 无法将 java.util.ArrayList 的实例反序列化出 VALUE_STRING

转载 作者:IT老高 更新时间:2023-10-28 12:46:01 29 4
gpt4 key购买 nike

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

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

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

在客户端,我使用 gson 将 JSON 表示形式转换为 java 对象。然后,我将对象传递给我的 REST 服务,它工作正常。

问题:

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

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

服务无法反序列化对象。

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: Can not deserialize instance of ArrayList out of String)。尽管如此,我并没有控制 ObjectMapper,因为在服务端它是由 Jackson 透明地制作的。

问题:

有没有办法在服务端配置ObjectMapper来启用ACCEPT_SINGLE_VALUE_AS_ARRAY?注释? 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());
}
...

最佳答案

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

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

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 定义中...

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

...其余的一切都由 jersey/jackson 透明地完成。

关于java - 无法将 java.util.ArrayList 的实例反序列化出 VALUE_STRING,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14588727/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com