Jackson 没有使用 JSON 根元素
Jackson not consuming the JSON root element
我正在使用 JAX-RS + Jersey 来使用 Web 服务请求并使用 Jackson 来翻译 JSON 数据:
@Path("/")
public class JAXRSRestController {
@Path("/jsonRequest")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response submitJsonRequest(SampleObject sampleObject, @Context HttpHeaders headers)
{
Ack ack = new Ack();
ack.setUniqueId(sampleObject.getId());
ack.setType(sampleObject.getName());
return Response.ok().entity(ack).build();
}
}
这里如果请求是以下格式,则不会被消费:
{
"sampleObject": {
"id": "12345",
"name": "somename"
}
}
但是如果请求格式如下,则会被消费:
{
"id": "12345",
"name": "somename"
}
如何让控制器也使用 Json 根元素?
样本对象class:
import org.codehaus.jackson.map.annotate.JsonRootName;
@XmlRootElement(name = "sampleObject")
@JsonRootName(value = "sampleObject")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SampleObject", propOrder = {
"id",
"name"
})
public class SampleObject
{
protected String id;
protected String name;
public SampleObject(){}
public SampleObject(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
web.xml:
<?xml version="1.0" encoding= "UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<display-name>Wed Application</display-name>
<servlet>
<servlet-name>Jersey RESTFul WebSerivce</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>com.jaxrs.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey RESTFul WebSerivce</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
我能想到两种方法。如果这在您的应用程序中很常见,我建议您在 ObjectMapper
上启用展开。如果这是一次性情况,包装器对象是个不错的选择。
一个。启用展开
@JsonRootName
仅在 ObjectMapper
上启用展开时才适用。您可以使用反序列化功能来完成此操作。请注意,这将解包所有请求:
public CustomObjectMapper() {
super();
enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
}
如果您还没有注册自定义 ObjectMapper
,那么您将需要添加一个 provider to register your custom config with Jersey. This answer 解释如何完成它。
乙。创建包装器
如果不想全局展开,可以创建一个简单的包装器对象并省略 @JsonRootName
注解:
public class SampleObjectWrapper {
public SampleObject sampleObject;
}
然后更新您的资源方法签名以接受包装器:
public Response submitJsonRequest(SampleObjectWrapper sampleObjectWrapper, @Context HttpHeaders headers)
我正在使用 JAX-RS + Jersey 来使用 Web 服务请求并使用 Jackson 来翻译 JSON 数据:
@Path("/")
public class JAXRSRestController {
@Path("/jsonRequest")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response submitJsonRequest(SampleObject sampleObject, @Context HttpHeaders headers)
{
Ack ack = new Ack();
ack.setUniqueId(sampleObject.getId());
ack.setType(sampleObject.getName());
return Response.ok().entity(ack).build();
}
}
这里如果请求是以下格式,则不会被消费:
{
"sampleObject": {
"id": "12345",
"name": "somename"
}
}
但是如果请求格式如下,则会被消费:
{
"id": "12345",
"name": "somename"
}
如何让控制器也使用 Json 根元素?
样本对象class:
import org.codehaus.jackson.map.annotate.JsonRootName;
@XmlRootElement(name = "sampleObject")
@JsonRootName(value = "sampleObject")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SampleObject", propOrder = {
"id",
"name"
})
public class SampleObject
{
protected String id;
protected String name;
public SampleObject(){}
public SampleObject(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
web.xml:
<?xml version="1.0" encoding= "UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<display-name>Wed Application</display-name>
<servlet>
<servlet-name>Jersey RESTFul WebSerivce</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>com.jaxrs.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey RESTFul WebSerivce</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
我能想到两种方法。如果这在您的应用程序中很常见,我建议您在 ObjectMapper
上启用展开。如果这是一次性情况,包装器对象是个不错的选择。
一个。启用展开
@JsonRootName
仅在 ObjectMapper
上启用展开时才适用。您可以使用反序列化功能来完成此操作。请注意,这将解包所有请求:
public CustomObjectMapper() {
super();
enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
}
如果您还没有注册自定义 ObjectMapper
,那么您将需要添加一个 provider to register your custom config with Jersey. This answer 解释如何完成它。
乙。创建包装器
如果不想全局展开,可以创建一个简单的包装器对象并省略 @JsonRootName
注解:
public class SampleObjectWrapper {
public SampleObject sampleObject;
}
然后更新您的资源方法签名以接受包装器:
public Response submitJsonRequest(SampleObjectWrapper sampleObjectWrapper, @Context HttpHeaders headers)