互聯網上有很多如何使用RESTful Client API的東西。 這些是基礎。 但是,盡管該主題看起來微不足道,但仍然存在一些障礙,尤其是對于初學者而言。
在這篇文章中,我將嘗試總結我的專業知識,以及我如何在實際項目中做到這一點。 我通常使用Jersey(用于構建RESTful服務的參考實現)。 參見例如我的另一篇文章 。 在本文中,我將從JSF bean調用真正的遠程服務。 讓我們編寫一個會話范圍的bean RestClient。
package com.cc.metadata.jsf.controller.common;import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;/*** This class encapsulates some basic REST client API.*/
@ManagedBean
@SessionScoped
public class RestClient implements Serializable {private transient Client client;public String SERVICE_BASE_URI;@PostConstructprotected void initialize() {FacesContext fc = FacesContext.getCurrentInstance();SERVICE_BASE_URI = fc.getExternalContext().getInitParameter('metadata.serviceBaseURI');client = Client.create();}public WebResource getWebResource(String relativeUrl) {if (client == null) {initialize();}return client.resource(SERVICE_BASE_URI + relativeUrl);}public ClientResponse clientGetResponse(String relativeUrl) {WebResource webResource = client.resource(SERVICE_BASE_URI + relativeUrl);return webResource.accept('application/json').get(ClientResponse.class);}
}
在此類中,我們獲得了在web.xml中指定(配置)的服務基礎URI。
<context-param><param-name>metadata.serviceBaseURI</param-name><param-value>http://somehost/metadata/</param-value>
</context-param>
此外,我們編寫了兩種方法來接收遠程資源。 我們打算接收JSON格式的資源,并將其轉換為Java對象。 下一個bean演示了如何對GET請求執行此任務。 Bean HistoryBean通過使用GsonConverter將接收到的JSON轉換為Document對象。 最后兩節將不在此處顯示(沒關系)。 Document是一個簡單的POJO,而GsonConverter是一個包裝Gson的單例實例。
package com.cc.metadata.jsf.controller.history;import com.cc.metadata.jsf.controller.common.RestClient;
import com.cc.metadata.jsf.util.GsonConverter;
import com.cc.metadata.model.Document;import com.sun.jersey.api.client.ClientResponse;import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;/*** Bean getting history of the last extracted documents.*/
@ManagedBean
@ViewScoped
public class HistoryBean implements Serializable {@ManagedProperty(value = '#{restClient}')private RestClient restClient;private List<Document> documents;private String jsonHistory;public List<Document> getDocuments() {if (documents != null) {return documents;}ClientResponse response = restClient.clientGetResponse('history');if (response.getStatus() != 200) {throw new RuntimeException('Failed service call: HTTP error code : ' + response.getStatus());}// get history as JSONjsonHistory = response.getEntity(String.class);// convert to Java array / list of Document instancesDocument[] docs = GsonConverter.getGson().fromJson(jsonHistory, Document[].class);documents = Arrays.asList(docs);return documents;}// getter / setter...
}
下一個bean演示了如何通過POST與遠程服務進行通信。 我們打算發送上傳文件的內容。 我使用PrimeFaces的 FileUpload組件,以便可以從偵聽器的參數FileUploadEvent中提取內容作為InputStream。 這在這里并不重要,您還可以使用任何其他Web框架來獲取文件內容(也可以作為字節數組)。 更重要的是,看看如何處理RESTful Client類FormDataMultiPart和FormDataBodyPart。
package com.cc.metadata.jsf.controller.extract;import com.cc.metadata.jsf.controller.common.RestClient;
import com.cc.metadata.jsf.util.GsonConverter;
import com.cc.metadata.model.Document;import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataMultiPart;import org.primefaces.event.FileUploadEvent;import java.io.IOException;
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;import javax.ws.rs.core.MediaType;/*** Bean for extracting document properties (metadata).*/
@ManagedBean
@ViewScoped
public class ExtractBean implements Serializable {@ManagedProperty(value = '#{restClient}')private RestClient restClient;private String path;public void handleFileUpload(FileUploadEvent event) throws IOException {String fileName = event.getFile().getFileName();FormDataMultiPart fdmp = new FormDataMultiPart();FormDataBodyPart fdbp = new FormDataBodyPart(FormDataContentDisposition.name('file').fileName(fileName).build(),event.getFile().getInputstream(), MediaType.APPLICATION_OCTET_STREAM_TYPE);fdmp.bodyPart(fdbp);WebResource resource = restClient.getWebResource('extract');ClientResponse response = resource.accept('application/json').type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, fdmp);if (response.getStatus() != 200) {throw new RuntimeException('Failed service call: HTTP error code : ' + response.getStatus());}// get extracted document as JSONString jsonExtract = response.getEntity(String.class);// convert to Document instanceDocument doc = GsonConverter.getGson().fromJson(jsonExtract, Document.class);...}// getter / setter...
}
最后但并非最不重要的一點,我想演示如何使用任何查詢字符串(URL參數)發送GET請求。 下一個方法通過看起來像http:// somehost / metadata / extract?file = <some file path>的URL詢問遠程服務。
public void extractFile() {WebResource resource = restClient.getWebResource('extract');ClientResponse response = resource.queryParam('file', path).accept('application/json').get(ClientResponse.class);if (response.getStatus() != 200) {throw new RuntimeException('Failed service call: HTTP error code : ' + response.getStatus());}// get extracted document as JSONString jsonExtract = response.getEntity(String.class);// convert to Document instanceDocument doc = GsonConverter.getGson().fromJson(jsonExtract, Document.class);...
}
參考:在我們的軟件開發博客上,來自我們JCG合作伙伴 Oleg Varaksin的RESTful Client API進行GET / POST 。
翻譯自: https://www.javacodegeeks.com/2013/01/get-post-with-restful-client-api.html