当前位置: 首页 > 知识库问答 >
问题:

JAX-RS JSON在编组后缺少子对象

臧俊杰
2023-03-14

我使用Glassfish、EclipseLink和JAX-RS提供REST服务,该服务通过AngularJS/AJAX从网站调用。我返回一个类型为SalesOrder的JSON对象,该对象具有一个类型为List的名为lineItems的属性

我已经成功地调用了REST资源,并返回了一个表示父Salesorder对象的JSON对象,但是,即使服务器端日志表明响应对象具有带有(2)SalesOrderLine对象的Salesorder实体,客户端/浏览器端的JSON对象缺少对子lineItems列表或其内容的任何引用。

Glassfish log contents:
2015-05-03T18:38:30.480-0600|Info: SalesOrder found with UID: 51
2015-05-03T18:38:30.480-0600|Info: Number of line items sent back to the REST service with the order is: 2
2015-05-03T18:38:30.480-0600|Info: Item Quantity is: 10
2015-05-03T18:38:30.480-0600|Info: Item Quantity is: 5
2015-05-03T18:38:30.480-0600|Info: Response status: 200
2015-05-03T18:38:30.480-0600|Info: Response status info: OK
2015-05-03T18:38:30.480-0600|Info: Response class: class org.glassfish.jersey.message.internal.OutboundJaxrsResponse
2015-05-03T18:38:30.480-0600|Info: Response length: -1
2015-05-03T18:38:30.480-0600|Info: Response media type: application/json
2015-05-03T18:38:30.480-0600|Info: Response entity: business.salesOrderMgmt.entity.SalesOrder@2a461205
2015-05-03T18:38:30.480-0600|Info: Response entity number of line items: 2
2015-05-03T18:38:30.481-0600|Info: Response is: OutboundJaxrsResponse{status=200, reason=OK, hasEntity=true, closed=false, buffered=false}

客户端/浏览器端的JSON对象:

{
    "salesOrderUid": 51,
    "orderNumber": "1428002042749",
    "billToCity": "Golden",
    "billToFirstName": "Duke",
    "billToLastName": "Developer",
    "billToState": "CO",
    "billToStreetName": "Technology Row",
    "billToStreetNumber": "12345",
    "billToUnitNumber": null,
    "billToZipCode": 80401,
    "creditCardCsv": 123,
    "creditCardExpirationDate": 1483254001000,
    "creditCardNumber": "123456789012",
    "creditCardType": "Visa",
    "emailAddress": "ddeveloper@techexpertconsulting.com",
    "nameOnCreditCard": "Duke Developer",
    "salesOrderDate": 1428002043000,
    "salesOrderStatus": "New",
    "shipToCity": "Golden",
    "shipToState": "CO",
    "shipToStreetName": "Technology Row",
    "shipToStreetNumber": "12345",
    "shipToUnitNumber": null,
    "shipToZipCode": 80401,
    "promoCode": "Test",
    "discount": 5,
    "salesTax": 3.2500000000000001804112415015879378188401460647583007812500,
    "shipping": 10,
    "total": 78.2500000000000001804112415015879378188401460647583007812500
}

因此,响应对象的编组似乎正在从子对象中删除。

有没有人看到这一点并想出了解决方法?

共有2个答案

终波涛
2023-03-14

感谢您的回复。在我看到这些之前,我最终将以下注释添加到我的实体类中...这有效,所以我没有尝试@XmlId和@XmlIdRef注释。不确定哪一组更好(@Xml... vs@Json...)?

在父(SalesOrder)实体上:@OneToMany(targetEntity=SalesOrderLine.class,cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy=“SalesOrder”)@JsonManagedReference private List lineItems;

在子(SalesOrderLine)实体上:@manytone@PrimaryKeyJoinColumn(name=“SALES\u ORDER\u UID”)@JsonBackReference@JsonIgnore private SalesOrder SalesOrder;

这是可行的,但后来我遇到了一个Glassfish bug“部署一个基本的webapp,3个类,在部署后的第一次尝试中,未能以正确的序列化JSON响应进行响应。”链接:https://java.net/jira/browse/GLASSFISH-21141针对open bug的解决方案建议将Jackson JAR下载到Glassfish模块目录,并删除OSGI缓存。我能够在不删除缓存的情况下使其工作。我的步骤是:1。停止Glassfish 2。下载参考3的(6)个Jackson jars。重新启动Glassfish

邹英光
2023-03-14

从这里的答案可以看出,您已经发现了使用XmlTransient来避免循环依赖。问题是,在编组/解编时,它完全忽略了属性。

那么我们如何解决这个问题呢?鉴于您是如何使用Glassfish的,它默认使用MOXy进行JSON处理,您可以简单地使用@XmlID@XmlIDREF。下面是我用来测试的

public class SalesOrder {

    private String id;
    private List<SalesOrderLine> salesOrderItems;

    @XmlID
    public String getId() { return id; }
    ...
}

public class SalesOrderLine {
    private String id;
    private String item;
    private SalesOrder salesOrder;

    @XmlIDREF
    public SalesOrder getSalesOrder() { return salesOrder; }
    ...
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getSalesOrder() {
    SalesOrder salesOrder = new SalesOrder("12345");

    List<SalesOrderLine> salesOrderItems = new ArrayList<>();
    SalesOrderLine line = new SalesOrderLine("123", "item1", salesOrder);
    salesOrderItems.add(line);
    line = new SalesOrderLine("124", "item2", salesOrder);
    salesOrderItems.add(line);

    salesOrder.setSalesOrderItems(salesOrderItems);

    return Response.ok(salesOrder).build();
}

而且效果很好。SalesOrder id用作SalesOrder对象中的值。如果没有这些注释,我将从MOXy获得循环依赖性错误。

注意:根据我测试的结果,考虑到使用了JAXB注释支持模块,该解决方案也适用于Jackson。

 类似资料:
  • 我是React的初学者,所以请对我有耐心。) 我有一个父组件,它有两个不同的按钮,可以触发子组件,子组件是一个模态,根据哪个按钮触发了模态,子组件内部必须显示不同的内容。这两个组件都是功能组件。子模式应该通过道具从父模式接收触发按钮的值。该按钮的名称是一个数字,对应于子组件中定义的数组中的对象索引。 当我安慰的时候。记录道具,我看到它们被传递到模态三次。第一次按钮的值确实通过道具传递,但在第二段和

  • 我有一个测试,它正在测试一个Spring@Service类。这个服务类autoworitory在一个dao@存储库中。dao还在一个类中autowires以提供额外的功能。我想模仿dao中的调用,所以我有如下内容: 服务中对getAnalysis的调用调用dao方法nameExists,我想从Expects块中的mockedNameExists返回结果,但我不知道我做错了什么。

  • 我正在使用Envers来审核表,但它正在为未知/不存在的表创建一些审核表。它看起来像多对一关系的多对多关系审计表。 这是对的吗?如果是,为什么? 但当我尝试删除和HorarioFixo时,我遇到了一个错误。 我收到的错误: 这是SQL重复: 所有这些都是代码的一部分。如果你需要更多,请留下评论。 我的班级: 我的映射: 新罕布什尔州和恩维尔斯配置:

  • 我对片段有问题,或者更确切地说是我希望它们工作的方式有问题。 在我的活动中,我有一个布局容器(R.id.container1),我在启动时以编程方式向其中添加一个片段(FragMain)。在片段中,我有2个片段(Frag1、Frag2)和一个ViewPager,它通过FragmentPagerAdapter加载其他几个片段(FragA、FragB、FragC、FragD、FragE)。 按下一个按

  • 我将我的Fabric8 Spring Boot Camel pom.xml升级到使用Camel 2.16.0,但并非所有组件都在2.16.0中可用 我不得不将以下组件保留在2.15.3,因为我得到了2.16.0版本的“丢失项目”: 骆驼指标 骆驼jsonpath 骆驼Spring靴 这些在Camel 2.16.0中不可用吗? 我使用的是Fabric8版本2.2.46和Spring Boot版本1.

  • 运行flutter doctor时,即使我安装了cmdline tools,也会出现错误{cmdline tools component is missing},如下所示: 我还运行c:/sdk/tools/bin/sdkmanager--安装“cmdline tools;latest”,输出显示如下所示,