java - Jackson JSON 生成 HTTP 状态 500,XML 有效

标签 java xml json jaxb jackson

我目前正在使用 Jackson 将 Java 对象序列化为 JSON 和 XML 作为 REST 网络服务的响应。我有以下带注释的 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 中都能完美工作(事实上,还有更多原始字段)。但是,从我添加 OnlineCompetitorView 列表的那一刻起,JSON 序列化就不再起作用,并导致应用程序生成 500 的 HTTP 状态(“内部服务器错误”)。但是,当我使用 application/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 工作正常,但是当我从服务请求 application/json 时,它 (GlassFish 4.0) 会产生一个内部服务器错误。这是 OnlineCompetitorView 的注释方式:

@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;

我也尝试过将 @XmlRootElement-annotation 添加到 OnlineCompetitorView,但这并没有改变任何东西。因为我没有从 GlassFish 收到任何错误,所以我真的不知道如何解决这个问题。简单的网络服务如下所示:

@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(虽然更复杂的“Product”-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 应用程序,而且我从来不需要添加属性文件或任何其他内容,而且它始终有效。

互联网上的一些人认为这是类加载器的问题(如 here )但是,再一次,我不必设置一些类加载器,因为我使用 Java EE,所以 XML/JSON 对象的编码和解码应该自动工作。此外,超链接中提出的解决方案(添加类加载器 XML 属性)对我不起作用。

我不明白为什么系统如此不一致。一些 RESTful 方法同时适用于 XML 和 JSON。其中一些仅适用于 XML,而另一些则根本不起作用(在同一个应用程序中!)。

我真的希望有人能帮我找到解决这个问题的方法!

最佳答案

对于遇到与我相同类型的问题但无法弄清楚原因的人:我自己找到了解决方案。我没有完全意识到要序列化为 XML/JSON 的 POJO 对象需要有一个零参数构造函数。这包括原始对象中使用的集合。

所以在我的例子中:我的“ProductDetailsView”对象有一个“OnlineCompetitorView”对象列表。 ProductDetailsView 和 OnlineCompetitorView 都需要有一个零参数构造函数。对于某些人来说,这可能是显而易见的,但我认为分享这些信息是明智的。我无意中在这个 link 的开头帖子中找到了这个信息,所以我想对此表示赞赏。

关于java - Jackson JSON 生成 HTTP 状态 500,XML 有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19536094/

相关文章:

java - 从项目(ActionBar)启动 Activity ?

javascript - 单独打印json元素

php - JSON 从 PDO 查询返回错误值

java - 获取xml元素的文本内容

c# - XmlSerializer - 将不同元素反序列化为相同元素的集合

html - Umbraco Json 到 css 类 ="[]"

java - Netbeans GUI 不显示

java - ActiveMq 结合 Tomcat

java - 向 Web 应用程序添加搜索功能和页面支持

java - xml解析器,一项