【问题标题】:Jersey JAX-RS 3 level nested object has null valueJersey JAX-RS 3 级嵌套对象具有空值
【发布时间】:2023-03-31 09:48:01
【问题描述】:

我有以下需要解析的 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;
}

PaymillEvent:

@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
    @XmlElement(name = "event_type") @DocumentationExample(value = "subscription.succeeded") private String eventType;
    @XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}

PaymillEventResource:

@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
    private PaymillClient client;
    private PaymillOffer offer;
    private PaymillSubscription subscription;
}

Paymill订阅:

@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
    private PaymillClient client;
    private PaymillOffer offer;
}

PaymillClient:

@XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
    @DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}

API 端点代码:

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
}

【问题讨论】:

  • 你能给我们列出 PaymillSubscription 吗?
  • 我的错,忘记了 PaymillSubscription,它也有 PaymillClient。所以这不是问题。还编辑并添加了 PaymillSubscription。 PaymillEventResource 和 PaymillSubscription 都包含 PaymillClient,因为有 2 个不同的 API 端点在任一对象中返回客户端(我知道,不漂亮,但这不取决于我)。无论哪种方式,PaymillClient 在这两种情况下都是 null。
  • 你不应该在 paymillSubscription 上调用 getClient() 而不是 getPaymillClient() 吗?
  • 现在试过了。仍然为空。
  • 看来我找到了答案:)

标签: jaxb jersey jax-rs jersey-2.0


【解决方案1】:

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

1. 如果您要从 JSON 中删除所有空值字段,那么一切都会完美。

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

@XmlAccessorType(XmlAccessType.FIELD)
public class Test {
    private String id;
}

并且会在订阅对象的最后一个空值字段和“客户”字段之间发送这个“测试”对象:

"test":{"id":"sadas"},
"client":{ 
    "id":"client_c0c24aa7f97e1b8ed15d"
 }

那么“test”将为空,但“client”将按预期进行解析。

3. 如果您将所有空值对象添加到模型中(我的意思是,在 PaymillSubscription 类中创建相应的字段),那么一切都会完美。

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

【讨论】:

  • 1) 你的意思是像 app_id 和 cancelled_at 这样的属性?如果是这样,就像我说的那样,我根本无法更改请求 JSON。 2) 在 JSON 中添加测试模型?我想和 1 一样,不能改变 JSON。 3)我认为这是可行的,我现在就试试。
  • 是的。你可以试试我在 2) 或 3) 中写的。
  • 大声笑,它似乎使用你的第三个想法。很好地找到了解决方案,但是为什么它不能处理模型内部未声明的空值呢?只是泽西岛内部的一个错误?
  • 我潜伏了一点,似乎没有。例如,当我使用 Jackson 而不是 MOXy 时,它直接将 JSON 中的未知字段归咎于我。看来,默认情况下,JAXB 规范不允许带有无法识别字段的 JSON(不幸的是,我找不到任何可以证明我的话的东西)。
猜你喜欢
  • 2016-04-13
  • 2020-12-07
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
相关资源
最近更新 更多