2014-12-04 28 views
3

創建RESTful Web服務客戶端似乎有大約澤西1.x中創建RESTful客戶的例子很多,但不澤西2.0或以上。 我提到了其他問題和澤西島的網站,但由於澤西島2.0和以前版本之間的差異,我仍然無法爲REST創建客戶端。 所以我想問一些建議。如何通過Jersey2.0以上

到目前爲止,我的編碼是這樣的。

ClientConfig config = new ClientConfig(); 
Client client = ClientBuilder.newClient(config); 
WebTarget target = client.target("http://localhost:8080/CustomerBack2211/webresources/entities.customer"); 

Invocation.Builder invocationBuilder = target.request(MediaType.TEXT_XML_TYPE); 
Response response = invocationBuilder.get(); 
System.out.println(response.getStatus()); 
System.out.println(response.readEntity(String.class)); 

這產生了406錯誤。但是,當我試圖通過Glassfish服務器測試RESTful服務時,測試工作正常,並且服務器端類的@GET方法具有@Produces({「application/xml」,「application/json」}) 。 所以我不明白爲什麼上面的代碼在Java應用程序中產生了406錯誤。

(通過以下方式,即客戶端已經@GET方法)

@GET 
@Path("{id}") 
@Produces({"application/xml", "application/json"}) 
public Customer find(@PathParam("id") Integer id) { 
    return super.find(id); 
} 

@GET 
@Override 
@Produces({ "application/xml"}) 
public List<Customer> findAll() { 
    return super.findAll(); 
} 

有任何影響,你看到我做錯了什麼,或者你可以請提出一個RESTful客戶端的例子嗎? 任何建議將有所幫助......提前致謝!


此外,我會很感激,如果你將提供有關如何調用像GET方法,PUT和適當的參數刪除。 當我在Glassfish RESTful測試中測試服務器端類時,我只需要輸入一個ID號(即整數值)。但是,似乎我需要將「類」和/或「實體」值設置爲參數,但我無法在澤西島網站上看到與它們相關的任何信息。

回答

3

對於第一個代碼塊:

406 means Not Acceptable

看看你的request()方法target.request(MediaType.TEXT_XML_TYPE)。從request()如果狀態

Invocation.Builder request(MediaType... acceptedResponseTypes)

Start building a request to the targeted web resource and define the accepted response media types. Invoking this method is identical to:

webTarget.request().accept(types);

所以基本上的Javadoc中,在你的要求,你是說你只Accept: text/plain會。現在看看你的資源方法。看看@Produces。他們都沒有「產生」text/plain。這都是json或xml。這就是爲什麼你會得到例外。在客戶端將接受更改爲application/xml(或MediaType.APPLICATION_XML),並且不應再發生此錯誤。

對於第二個問題:我假設你的意思是,爲什麼當你從瀏覽器中測試它時會工作。

如果您通過簡單地輸入url從瀏覽器發送請求,它將發送請求與許多Accept類型。如果您有螢火蟲(適用於Firefox)或開發工具(Chrome瀏覽器),如果你發送一個請求,你會看到一個類似於頭

Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 

你可以在那裏看到application/xml。即使application/xml不在那裏,通配符*/*就在那裏,所以基本上幾乎所有媒體類型在瀏覽器中工作時都可以作爲返回類型。

對於你最後一個問題:

看爲SyncInvoker的API,它Invocation.Builder從延伸。您會看到不同的過載putpost方法,其中大部分方法如您所述接受Entity

有幾種不同的方法來構建Entity,所有這些方法都使用其中一種靜態方法。下面是一些

  • Entity.entity(身體,mediaType的)
  • Entity.json(體)
  • Entity.xml(體)

還有更多(見上實體鏈接)。但是,所有這些靜態方法返回Entity。因此,我們可以這樣做

// resource method 
@POST 
@Consumes(MediaType.APPLICATION_XML) 
public Response getResponse(Customer customer) { ... } 

// some model class 
@XmlRootElement 
public class Customer { ... } 

// client request 
Customer customer = new Customer(); 
Response response = target.request().post(Entity.xml(customer)); 

內部,Customer將得到轉換爲XML。如果您使用Entity.json將被轉換爲JSON,但是您需要確保您具有JSON提供程序依賴項。澤西島默認不會有一個。多見於Support for Common Media Type Representations


另外請注意,您的方法find,當你試圖讓該方法的請求,該請求應與整數值結束,因爲這是爲{id}路徑參數指定的類型。

+0

非常感謝您的建議。 現在我可以理解它生產了406個。 你能告訴更多關於你的建議的最後2行嗎? – Hiroki 2014-12-04 09:25:22

+0

我試圖通過導入「customerEnd.Customer;」來使用「客戶」類。 這是一個在服務器端製作的包,包含「客戶」類。 導入此軟件包不會導致任何錯誤,可能是因爲我已將服務器端類的WAR文件添加到此客戶端。 但是,在構建項目後,它會產生錯誤。 這將是必要的,使用這個類,所以你看到什麼我需要做的導入這個包? – Hiroki 2014-12-04 09:30:11

+0

你的'@ Path'是'@Path(「{id}」)''。在你想獲得id的路徑段值的方法中。我要說的是,這個請求應該以該ID結束,因爲你可以在該方法中使用它。像'http://..../ customers/1',其中'1'是傳遞給方法的id。 – 2014-12-04 09:32:44