2016-05-16 51 views
3

我想創建一個使用澤西非常簡單的REST服務。下面是服務代碼MessageBodyWriter找不到媒體類型=應用程序/ JSON時返回JSON在REST Web服務與澤西島

@Path("/UserService") 
public class UserService { 

    @GET 
    @Path("/users") 
    @Produces(MediaType.APPLICATION_XML) 
    public List<User> getUsers() { 
     User user = new User(1, "Thomas", "Greene"); 
     List<User> userList = new ArrayList<User>(); 
     userList.add(user); 
     return userList; 
    } 
} 

當我通過郵路運行它,它返回我的XML響應

XML response in Postman

現在,我希望得到一個JSON響應返回。所以,我改變了介質類型來application/json

@Path("/UserService") 
public class UserService { 

    @GET 
    @Path("/users") 
    @Produces(MediaType.APPLICATION_JSON) 
    public List<User> getUsers(){ 
     User user = new User(1, "Thomas", "Greene"); 
     List<User> userList = new ArrayList<User>(); 
     userList.add(user); 
     return userList; 
    }  
} 

它給了我在Tomcat的日誌下面的錯誤:

重度:MessageBodyWriter找不到媒體類型=應用程序/ JSON,類型=級Java。 util.ArrayList,genericType = java.util.List。

有人可以請指導我如何獲得JSON響應嗎?

回答

8

要使用傑克遜作爲2.X的JSON提供你需要jersey-media-json-jackson模塊添加到您的pom.xml文件:

<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-json-jackson</artifactId> 
    <version>2.22.2</version> 
</dependency> 

然後在您的Application/ResourceConfig子類中註冊JacksonFeature

欲瞭解更多詳情,請看看澤西島documentation

+0

我沒有使用maven。我剛剛使用eclispe創建了一個'動態Web項目'。這給了我一個WEB-INF/lib目錄。我在lib目錄中添加了'com.fasterxml.jackson.core.jar','com.fasterxml.jackson.databind.jar'和'jackson-annotations-2.1.2.jar'。最後,我只是將這個項目導出爲戰爭並在Tomcat中部署。 所以,我既沒有pom.xml,也沒有找到Application/ResourceConfig。不會將這3個罐子添加到WEB-INF/lib中就足夠了嗎? – kayasa

+0

@kayasa您可以手動添加依賴關係(查看依賴關係將需要[這裏](http://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson/2.22)。 2))。但我建議你現在使用Maven。說真的,*沒有理由手動管理你的依賴關係。要將現有項目轉換爲Maven項目,請查看[這裏](http://stackoverflow.com/q/2449461/1426227)。 –

+0

感謝您的建議。我同意使用Maven是個好主意。但是,我對澤西和Maven都是新手,所以一次只想做一件事。在選擇Maven之前,我希望獲得'Hello World'REST示例。 – kayasa

1

您需要在您的類路徑上使用json序列化程序來使其工作。

只需添加傑克遜和澤西島將在作家中使用它。 例如如果你正在使用maven,將其添加到pom.xml中

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-core</artifactId> 
    <version>2.7.4</version> 
</dependency> 
+0

比你。我在WEB-INF/lib中添加了'jackson-2.1.0-all.jar',但這並沒有幫助。 – kayasa

+0

我也嘗試刪除'jackson-2.1.0-all.jar',而是將下面的3個jar添加到WEB-INF/lib - com.fasterxml.jackson.core.jar - com.fasterxml.jackson.databind。 jar - jackson-annotations-2.1.2.jar 我沒有pom.xml,因爲我沒有使用maven。我希望將這三個jar添加到WEB-INF/lib來解決問題,但它沒有。它是否也需要更改代碼? – kayasa

+0

我試過了。雖然添加傑克遜核心依賴沒有幫助解決錯誤,但我想了解傑克遜jar如何解決錯誤的內部。 –

1

我有點不高興JAXB此刻的結合爲好,所以讓我總結一下我發現在這裏 - 請糾正我,如果我說一些愚蠢的事:

  1. 當然,你必須有一個庫做JSON(de)序列化,在我的情況下是Moxy。
  2. 你必須告訴JAXB它應該支持哪些類。有多種方法可以做到這一點,最簡單的方法似乎是在與類匹配的目錄中添加jaxb.properties文件,其唯一內容是文本javax.xml.bind.context.factory = org.eclipse。 persistence.jaxb.JAXBContextFactory。隨着我的意思是目錄,如果你的類在目錄的src/main/java的有包com.pkg1.entities,在的src/main /資源添加此文件,並有作爲COM /的pkg1 /entities/jaxb.properties
  3. 默認情況下JAXB在POJO上工作。所以你需要有一個沒有參數的構造函數,一個get和set方法。只有這個字段將出現在JSON中。
  4. 我常常做的事是添加第二個構造函數,它將傳入運行時對象並將所有字段設置爲直接顯示。因此我不需要,也不需要set-method。解決方案是使用@XmlElement註釋get方法。
  5. 我說你需要一個空的/默認的構造函數嗎?我花了三個小時找出class1工作正常的原因,class2得到了MessageBodyWriter錯誤。我忘記了構造函數。 Grrrrr。
  6. 當類配置正常,但其中一個字段返回無法序列化的類型時,會得到相同的錯誤(我相信)。
  7. 我相信有一個案例,其中類註釋@XmlRootElement導致該錯誤。不確定,但我目前幾乎不使用該註釋。
  8. 如果您有一個List作爲要轉換成Json數組的元素之一,那麼JAXB將使用myAbstract類來進行序列化。不是很有用,你希望實際的對象被序列化。但是JAXB應該如何知道誰實現了/擴展了這個類?你必須告訴註解@XmlSeeAlso。所以MyAbstract類獲得類註釋@XmlSeeAlso({MyConcrete1.class,MyConcrete2.class})。至少Moxy確實增加了一個額外的類型字段告訴消費者它是哪一類。總體感覺。
  9. 儘管你可以返回userList最好的選擇是返回Response.ok()。entity(userList).build();然後你可以返回錯誤。從邏輯上講,它是一樣的。
  10. 注意你使用什麼樣的數據類型。字符串很好,ArrayList也是,Hashtable不是。取決於您使用的序列化程序。

我希望這可以幫助別人。

0

您的xml工作正常,所以我假設您的User類中有@XmlRootElement註釋。

事情是,它知道如何將其轉換爲xml與註釋@XmlRootElement,但它不知道如何將其轉換爲JSON。

所以製作它的一切轉換成JSON和XML的相同的註釋(即@XmlRootElement),我們可以添加

jersey-media-moxy-<whatever version>.jar

或Maven用戶

<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-moxy</artifactId> 
</dependency> 

還應該有沒有參數的構造函數

相關問題