我使用 Glassfish、EclipseLink 和 JAX-RS 来提供通过 AngularJS/AJAX 从网站调用的 REST 服务。我返回一个 SalesOrder
类型的 JSON 对象,该对象具有一个名为 lineItems
类型的属性,该属性在属性属性和 List<SalesOrderLine>
方法上都用 @OneToMany
注释。
我已成功调用 REST 资源并返回一个表示父 getLineItems()
对象的 JSON 对象,但是,即使服务器端日志指示响应对象具有一个带有 (2) SalesOrder
对象的 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
}
因此,响应对象的编码似乎正在丢弃子对象。
有人见过这个问题并知道如何解决吗?
最佳答案
从你的回答看here ,您已经发现了使用 @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 用作 SalesOrderLine
对象中的 salesOrder
值。如果没有这些注释,我会从 MOXy 收到循环依赖错误。
注意:根据我的测试,如果使用了 JAXB 注释支持模块,该解决方案也适用于 Jackson。
关于java - JAX-RS JSON 编码后缺少子对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30021187/