我有一个使用Jersey构建并部署在AppEngine中的REST服务。REST服务实现使用application/json
媒体类型的动词PUT
。数据绑定由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
。但是,我无法控制,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>
…其余所有工作都是由球衣/杰克逊透明完成的。
在客户端,我使用gson将JSON表示转换为java对象。然后,我将该对象传递给我的REST服务,它可以正常工作。 问题: 当我的JSON表示在集合中只有一个项时 客户端:
我的映射器是: 如果我删除列表freq并改为字符串freq,它可以工作,但我的JSON可以包含一个或多个freq,所以我需要创建一个列表。我得到的异常如下:
问题内容: 我正在尝试发布自定义对象。我在请求正文中的JSON是这样的: 处理请求的服务器端代码: 实体: 但是抛出一个异常: 问题答案: 问题是JSON-默认情况下不能反序列化为,因为它实际上不是JSON数组-看起来像这样: 由于你没有控制反序列化的确切过程(RestEasy确实如此)- 第一个选择是简单地将JSON作为a注入String,然后控制反序列化过程: 你不必自己进行操作便会失去一些便
我正在尝试发布一个自定义对象的。请求体中的JSON如下所示: 处理请求的服务器端代码: 实体: 但会引发异常:
无法将Json反序列化为列表集合。我使用的是Lombok,它保存字段变量: 我该怎么修好它?