Jaxb Jersey JAX-RS 3级嵌套对象具有空值

Jaxb Jersey JAX-RS 3级嵌套对象具有空值,jaxb,jersey,jax-rs,jersey-2.0,Jaxb,Jersey,Jax Rs,Jersey 2.0,我有下面需要解析的JSON代码。我正在使用相应的JAX-RS模型。问题是paymillClient对象为空。如果我在PaymillSubscription对象中添加currency作为字符串,它将返回EUR值,而不是null。因此,PaymillClient对象似乎有问题,而不是普通字符串。是否可以限制用于解析的嵌套对象的数量?例如,最多2个嵌套对象。因为在我的例子中有3个,所以它不起作用 不幸的是,我根本无法更改需要解析的JSON代码。我只需要让它与JAX-RS实现一起工作 { "e

我有下面需要解析的JSON代码。我正在使用相应的JAX-RS模型。问题是
paymillClient
对象为空。如果我在
PaymillSubscription
对象中添加
currency
作为字符串,它将返回
EUR
值,而不是null。因此,
PaymillClient
对象似乎有问题,而不是普通字符串。是否可以限制用于解析的嵌套对象的数量?例如,最多2个嵌套对象。因为在我的例子中有3个,所以它不起作用

不幸的是,我根本无法更改需要解析的JSON代码。我只需要让它与JAX-RS实现一起工作

{  
   "event":{  
      "event_type":"subscription.succeeded",
      "event_resource":{  
         "subscription":{  
            "id":"sub_29f144a3bc32c71f96e2",
            "offer":{  },
            "livemode":false,
            "amount":200,
            "temp_amount":null,
            "currency":"EUR",
            "name":"Monthly subscription",
            "interval":"1 MONTH",
            "trial_start":null,
            "trial_end":null,
            "period_of_validity":null,
            "end_of_period":null,
            "next_capture_at":1428939744,
            "created_at":1426264944,
            "updated_at":1426264944,
            "canceled_at":null,
            "payment":{  },
            "app_id":null,
            "is_canceled":false,
            "is_deleted":false,
            "status":"active",
            "client":{ 
              "id":"client_c0c24aa7f97e1b8ed15d" 
            }
         },
         "transaction":{  }
      },
      "created_at":1426264944,
      "app_id":null
   }
}
PaymillEventContainer:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventContainer
{
    private PaymillEvent event;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
    @XmlElement(name = "event_type") @DocumentationExample(value = "subscription.succeeded") private String eventType;
    @XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
    private PaymillClient client;
    private PaymillOffer offer;
    private PaymillSubscription subscription;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
    private PaymillClient client;
    private PaymillOffer offer;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
    @DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}
public Response postSubscriptionSucceeded(PaymillEventContainer paymillEventContainer)
    {
        PaymillEvent paymillEvent = paymillEventContainer.getPaymillEvent();
        PaymillEventResource paymillEventResource = paymillEvent.getEventResource();

        PaymillSubscription paymillSubscription = paymillEventResource.getSubscription();
        PaymillClient paymillClient = paymillSubscription.getPaymillClient();
        PaymillOffer paymillOffer = paymillSubscription.getPaymillOffer();

        String clientId = paymillClient.getId(); // NullPointerException
}
PaymillEvent:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventContainer
{
    private PaymillEvent event;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
    @XmlElement(name = "event_type") @DocumentationExample(value = "subscription.succeeded") private String eventType;
    @XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
    private PaymillClient client;
    private PaymillOffer offer;
    private PaymillSubscription subscription;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
    private PaymillClient client;
    private PaymillOffer offer;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
    @DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}
public Response postSubscriptionSucceeded(PaymillEventContainer paymillEventContainer)
    {
        PaymillEvent paymillEvent = paymillEventContainer.getPaymillEvent();
        PaymillEventResource paymillEventResource = paymillEvent.getEventResource();

        PaymillSubscription paymillSubscription = paymillEventResource.getSubscription();
        PaymillClient paymillClient = paymillSubscription.getPaymillClient();
        PaymillOffer paymillOffer = paymillSubscription.getPaymillOffer();

        String clientId = paymillClient.getId(); // NullPointerException
}
PaymillEventResource:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventContainer
{
    private PaymillEvent event;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
    @XmlElement(name = "event_type") @DocumentationExample(value = "subscription.succeeded") private String eventType;
    @XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
    private PaymillClient client;
    private PaymillOffer offer;
    private PaymillSubscription subscription;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
    private PaymillClient client;
    private PaymillOffer offer;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
    @DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}
public Response postSubscriptionSucceeded(PaymillEventContainer paymillEventContainer)
    {
        PaymillEvent paymillEvent = paymillEventContainer.getPaymillEvent();
        PaymillEventResource paymillEventResource = paymillEvent.getEventResource();

        PaymillSubscription paymillSubscription = paymillEventResource.getSubscription();
        PaymillClient paymillClient = paymillSubscription.getPaymillClient();
        PaymillOffer paymillOffer = paymillSubscription.getPaymillOffer();

        String clientId = paymillClient.getId(); // NullPointerException
}
付费订阅:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventContainer
{
    private PaymillEvent event;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
    @XmlElement(name = "event_type") @DocumentationExample(value = "subscription.succeeded") private String eventType;
    @XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
    private PaymillClient client;
    private PaymillOffer offer;
    private PaymillSubscription subscription;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
    private PaymillClient client;
    private PaymillOffer offer;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
    @DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}
public Response postSubscriptionSucceeded(PaymillEventContainer paymillEventContainer)
    {
        PaymillEvent paymillEvent = paymillEventContainer.getPaymillEvent();
        PaymillEventResource paymillEventResource = paymillEvent.getEventResource();

        PaymillSubscription paymillSubscription = paymillEventResource.getSubscription();
        PaymillClient paymillClient = paymillSubscription.getPaymillClient();
        PaymillOffer paymillOffer = paymillSubscription.getPaymillOffer();

        String clientId = paymillClient.getId(); // NullPointerException
}
PaymillClient:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventContainer
{
    private PaymillEvent event;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
    @XmlElement(name = "event_type") @DocumentationExample(value = "subscription.succeeded") private String eventType;
    @XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
    private PaymillClient client;
    private PaymillOffer offer;
    private PaymillSubscription subscription;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
    private PaymillClient client;
    private PaymillOffer offer;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
    @DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}
public Response postSubscriptionSucceeded(PaymillEventContainer paymillEventContainer)
    {
        PaymillEvent paymillEvent = paymillEventContainer.getPaymillEvent();
        PaymillEventResource paymillEventResource = paymillEvent.getEventResource();

        PaymillSubscription paymillSubscription = paymillEventResource.getSubscription();
        PaymillClient paymillClient = paymillSubscription.getPaymillClient();
        PaymillOffer paymillOffer = paymillSubscription.getPaymillOffer();

        String clientId = paymillClient.getId(); // NullPointerException
}
API端点代码:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventContainer
{
    private PaymillEvent event;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
    @XmlElement(name = "event_type") @DocumentationExample(value = "subscription.succeeded") private String eventType;
    @XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
    private PaymillClient client;
    private PaymillOffer offer;
    private PaymillSubscription subscription;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
    private PaymillClient client;
    private PaymillOffer offer;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
    @DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}
public Response postSubscriptionSucceeded(PaymillEventContainer paymillEventContainer)
    {
        PaymillEvent paymillEvent = paymillEventContainer.getPaymillEvent();
        PaymillEventResource paymillEventResource = paymillEvent.getEventResource();

        PaymillSubscription paymillSubscription = paymillEventResource.getSubscription();
        PaymillClient paymillClient = paymillSubscription.getPaymillClient();
        PaymillOffer paymillOffer = paymillSubscription.getPaymillOffer();

        String clientId = paymillClient.getId(); // NullPointerException
}

嗯。我试图在您的机器上运行您的代码,但也收到了null(注意,我使用MOXy来解组JSON)。然后,我尝试了一下,发现了一些非常有趣的事情:

1.如果您要从JSON中删除所有空值字段,则所有字段都可以正常工作。

2.如果您将向PaymillSubscription添加另一个字段。我添加了私有测试,其中测试为:

@XmlAccessorType(XmlAccessType.FIELD)
public class Test {
    private String id;
}
并将在订阅对象中最后一个空值字段和“客户端”字段之间发送此“测试”对象:

然后“test”将为null,但“client”将按预期进行解析。

3.若您将所有空值对象添加到模型中(我的意思是,在PaymillSubscription类中创建相应的字段),那个么所有的工作都非常完美。


看起来,默认情况下JAXB规范不允许JSON包含无法识别的字段,但MOXy仍然尝试解析它(有时会产生错误)。

您能给我们提供PaymillSubscription的列表吗?我的错,忘记了PaymillSubscription,它也有PaymillClient。所以这不是问题所在。编辑并添加了PaymillSubscription。PaymillEventResource和PaymillSubscription都包含PaymillClient,因为有两个不同的API端点在两个对象中返回客户机(我知道,这并不漂亮,但这不取决于我)。无论哪种方式,PaymillClient在这两种情况下都为null。您不应该在paymillSubscription上调用getClient()而不是getPaymillClient()?请立即尝试。仍然为空。似乎我找到了答案:)1)你是说app\u id和canceled\u at之类的属性?如果是这样,就像我说的,我根本无法更改请求JSON。2) 在JSON中添加测试模型?我猜和1一样,不能更改JSON。3) 我想这是可行的,我现在就试试。你可以试试我在2)或3)中写的东西,哈哈,看来它是用你的第三个想法工作的。很好地找到了解决方案,但是为什么它不能处理模型中未声明的空值呢?只是泽西岛内部的一个bug?我隐藏了一点,似乎没有。例如,当我使用Jackson而不是MOXy时,它直接将JSON中的未知字段归咎于我。看起来,默认情况下JAXB规范不允许JSON包含无法识别的字段(不幸的是,我找不到任何证明我的话的东西)。