[英]Jackson JSON generates HTTP status 500, XML works
我目前正在使用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中完美地工作(事實上,有更多的原始字段)。 但是,從我添加OnlineCompetitorView列表的那一刻起,JSON序列化就不再起作用,並導致應用程序生成HTTP狀態500(“內部服務器錯誤”)。 但是,當我使用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;
我也試過在OnlineCompetitorView中添加@ XmlRootElement-annotation,但這並沒有改變任何東西。 由於我沒有從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(雖然更復雜的'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應用程序,我從來沒有必要添加屬性文件,它始終有效。
互聯網上的一些人認為這是類加載器的問題(就像這里一樣)但是,我再一次,我從來沒有設置過一些類加載器,因為我使用Java EE,這種XML / JSON對象的編組和解組應該自動運行。 此外,超鏈接中提出的解決方案(添加類加載器XML屬性)對我不起作用。
我不明白為什么系統如此不一致。 一些RESTful方法適用於XML和JSON。 其中一些只能使用XML,而其中一些根本不起作用(在同一個應用程序中!)。
我真的希望有人能幫我找到解決這個問題的方法!
對於那些與我有同樣問題但無法弄清楚原因的人:我自己找到了解決方案。 我沒有完全意識到要序列化為XML / JSON的POJO對象需要具有零參數構造函數。 這包括原始對象中使用的集合。
所以在我的情況下:我的'ProductDetailsView'對象有一個'OnlineCompetitorView'對象列表。 ProductDetailsView和OnlineCompetitorView都需要一個零參數構造函數。 對於一些人來說可能很明顯,但我認為分享這些信息是明智的。 我在這個鏈接的開頭發帖中意外地發現了這些信息,所以我想對此給予一些信任。
我有完全相同的問題,但我確實在bean中沒有arg構造函數。 對我來說,解決方案是刪除bean聲明中的泛型。 因此,不是返回Bean,而是必須從服務返回Bean。 然后,奇跡般地,一切都奏效了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.