杰克逊没有消耗JSON根元素 [英] Jackson not consuming the JSON root element

查看:170
本文介绍了杰克逊没有消耗JSON根元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JAX-RS + Jersey来使用网络服务请求,杰克逊正在翻译JSON数据:

I'm using JAX-RS + Jersey to consume the web-service request and Jackson to translate JSON data:

@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();
    }
}

如果请求的格式如下,不会消耗:

Here if the request is in the below format, it would not be consumed:

{
  "sampleObject": {
    "id": "12345",
    "name": "somename"
  }
}

但如果请求采用以下格式,则会被使用:

But if the request is in the below format, it will be consumed:

{
    "id": "12345",
    "name": "somename"
}

如何让控制器同时使用Json根元素?

SampleObject类:

SampleObject 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 上启用解包。如果这是一次性的情况,包装器对象不是一个糟糕的选择。

There are two approaches I can think of. If this is a common occurrence in your application, I would recommend enabling unwrapping on your ObjectMapper. If this is a one-off situation, a wrapper object is not a bad option.

@JsonRootName 仅适用于在 ObjectMapper上启用展开。您可以使用反序列化功能完成此操作。请注意,这将解包所有请求:

@JsonRootName will only apply if unwrapping is enabled on the ObjectMapper. You can accomplish this with a deserialization feature. Note that this will unwrap all requests:

public CustomObjectMapper() {
   super();
   enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
}

如果您还没有自定义 ObjectMapper 已注册,然后您需要添加提供商以向Jersey注册您的自定义配置。 这个答案解释了如何做到这一点。

If you do not already have a custom ObjectMapper registered then you will need to add a provider to register your custom config with Jersey. This answer explains how do accomplish that.

如果您不想全局展开,可以创建一个简单的包装器对象并省略 @JsonRootName 注释:

If you do not want to unwrap globally, you can create a simple wrapper object and omit the @JsonRootName annotation:

public class SampleObjectWrapper {
   public SampleObject sampleObject;
}

然后更新资源方法签名以接受包装器:

Then update your resource method signature to accept the wrapper:

public Response submitJsonRequest(SampleObjectWrapper sampleObjectWrapper, @Context HttpHeaders headers)

这篇关于杰克逊没有消耗JSON根元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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