我目前正在使用Jackson将Java对象序列化为JSON和XML,作为REST Web服务的响应。我有以下带注释的 Java 对象:
@XmlRootElement(name = "Product")
@XmlAccessorType(XmlAccessType.FIELD)
public class ProductDetailsView {
@XmlElement
private int id;
@XmlElement
private long EAN;
@XmlElement
private String manufacturer;
@XmlElement
private String modelname;
@XmlElementWrapper(name = "onlineCompetitors")
@XmlElement(name = "competitor")
private List<OnlineCompetitorView> onlineCompetitors;
现在,前几个字段是基元类型,它们在 JSON 和 XML 中都能完美运行(事实上,还有更多的基元字段)。但是,从我添加OnlineRivalView列表的那一刻起,JSON序列化就不再起作用,并导致应用程序生成HTTP状态500("内部服务器错误")。但是,当我使用应用程序/xml作为接受的内容类型时,它可以完美运行。
正确的 XML 响应:
<Product>
<id>1</id>
<EAN>5901234123457</EAN>
<manufacturer>Samsung</manufacturer>
<onlineCompetitors>
<competitor>
<id>1</id>
<shopname>Shop1</shopname>
<rating>4</rating>
<productPrice>488.95</productPrice>
<stock>7</stock>
</competitor>
<competitor>
<id>2</id>
<shopname>Shop2</shopname>
<rating>5</rating>
<productPrice>498.95</productPrice>
<stock>12</stock>
</competitor>
</onlineCompetitors>
</product>
所以XML工作正常,但是当我从服务请求应用程序/json时,它(GlassFish 4.0)会创建内部服务器错误。以下是OnlineRivalView的注释方式:
@XmlAccessorType(XmlAccessType.FIELD)
public class OnlineCompetitorView {
@XmlElement
private final int id;
@XmlElement
private final String shopname;
@XmlElement
private final int rating;
@XmlElement
private final double productPrice;
@XmlElement
private final int stock;
我也尝试在OnlineRivalView中添加@XmlRootElement注释,但这并没有改变任何东西。由于我没有从GlassFish收到任何错误,我真的不知道如何解决问题。简单的 Web 服务如下所示:
@GET
@Path("/get/product/{ean}")
@Produces({"application/xml", "application/json"})
public ProductDetailsView getProduct(@PathParam("ean") Long EAN) {
ProductDetailsView pdv = service.getProductDetailsView(EAN);
return pdv;
}
那么,XML怎么可能正常工作,而JSON会产生内部服务器错误呢?有人可以帮助我解决这个问题吗?任何帮助将不胜感激!
编辑!
由于我仍然不知道为什么JSON不起作用,而XML却继续开发我的应用程序。在这样做的过程中,我偶然发现了一个新问题,可能与第一个问题有关,这就是我更新问题的原因。
我创建了一个小而简单的测试,它返回了一个非常简单的注释POJO,它不适用于XML或JSON(而更复杂的"产品"-POJO正在工作,尽管仅适用于XML)。
现在,错误日志仍然没有显示任何错误,但 glassfish 返回了一些东西:
FINE: Trying to locate com/eid/instoreapp/JSONView/jaxb.properties
FINE: not found
FINE: Checking system property javax.xml.bind.context.factory
FINE: not found
FINE: Checking system property javax.xml.bind.JAXBContext
FINE: not found
FINE: OSGi environment detected
我一直在对此进行一些研究,显然JAXB需要某种属性文件。现在,我已经构建了更多这样的 REST 应用程序,我从来不需要添加属性文件或任何东西,而且它总是有效。
互联网上的一些人认为这是类加载器的问题(就像这里一样),但是,再一次,我从来没有设置过一些类加载器,因为我使用Java EE,所以XML/JSON对象的编组和解组应该会自动工作。此外,超链接中提出的解决方案(添加类加载器 XML 属性)对我不起作用。
我不明白为什么系统如此不一致。一些 RESTful 方法在 XML 和 JSON 中都有效。其中一些仅适用于 XML,而另一些则根本不工作(在同一应用程序中!
我真的希望有人能帮助我找到解决这个问题的方法!
对于那些和我有同样问题并且不知道原因的人:我自己找到了解决方案。我没有完全意识到要序列化为 XML/JSON 的 POJO 对象需要有一个零参数构造函数。这包括原始对象中使用的集合。
所以就我而言:我的"ProductDetailsView"对象有一个"OnlineRivalView"对象列表。ProductDetailsView 和 OnlineRivalView 都需要有一个零参数构造函数。对于某些人来说,这可能是显而易见的,但我认为分享这些信息是明智的。我偶然发现了这些信息,在这个链接的开头帖子中,所以我想给它一些荣誉。
我遇到了完全相同的问题,但我在 bean 中确实有 no-arg 构造函数。 对我来说,解决方案是在 bean 的声明中删除泛型。 因此,我没有归还豆子,我不得不只归还豆豆。 然后,神奇的是,这一切都奏效了!