RESTful web services with Java (Jersey / JAX-RS).
這篇教學是從德國公司 vogella 的網站翻譯過來的,原文可以參考最底下的 Reference,教學內容講述了如何透過 Jersey 這套 JAX-RS reference implementation 來開發 RESTful web services
開發環境
Outline
What is REST?
REST 是一種基於 web 標準與 HTTP 協定的架構風格,最早在西元 2000 年時由 Roy Fielding 所提出
在 REST 的架構中,將一切都視為 resource,而 resource 可以通過 common interface 來存取,這些 common interface 則基於 HTTP standard methods 來設計
在 REST 架構中,我們通常會有一個 REST server 提供對 resource 的存取,以及 REST client 去存取修改 resource
所有 resource 都必須支援 HTTP common operations,resources 會有 global IDs(一般就是URIs) 識別
REST 也允許 resource 有不同的表示法,如 text, XML, JSON 等,REST client 可以通過 HTTP 協商來向 REST server 要求特定的資料表示格式
HTTP methods
一般 REST 架構中常見的 HTTP methods 為 PUT, GET, POST and DELETE 四種
RESTful web services
RESTful web services 是基於 HTTP methods 和 REST 的概念
RESTful web service 一般或有一個 base URI, 支援的 MIME-types (XML, text, JSON, user-defined, …) 和一系列的操作 (POST, GET, PUT, DELETE)
JAX-RS
Java 在 Java Specification Request (JSR) 311 中定義了對 REST 的支援,稱為 JAX-RS (The Java API for RESTful Web Services)
JAX-RS 宣告了REST 相關的 JAVA classes
Jeresey
Jersey is the reference implementation for the JSR 311 specification.
Jersey 提供了在 Java servlet container 中實現 Restful web services 的 library
在 server 端的部分,Jersey 提供一個 servlet implementation,它會掃描預先定義的 classes 來識別 RESTful resources
我們可以在 web.xml
設定檔中為我們的 web application 註冊這個 servlet
這個 servlet 的 base URL 為:
http://your_domain:port/display-name/url-pattern/path_from_rest_class
這個 servlet 會分析進入的 HTTP request,並選擇對應的 class and method 去回應 HTTP 請求,而 respond class and methods 的選擇可以參考下一段的 JAX-RS annotations
REST web application 基本包含了 data classes(resource) 和 service 兩部分,一般由不同的 packages 維護,Jersey servlet 則會根據 web.xml
去尋找對應的 packages 和 data classes
JAX-RS 也支援通過 Java Architecture for XML Binding (JAXB) 來建立 XML 和 JSON
JAX-RS annotations
Annotation | Description |
---|---|
@PATH(your_path) | Sets the path to base URL + /your_path. The base URL is based on your application name, the servlet and the URL pattern from the web.xml configuration file. |
@POST | Indicates that the following method will answer to an HTTP POST request. |
@GET | Indicates that the following method will answer to an HTTP GET request. |
@PUT | Indicates that the following method will answer to an HTTP PUT request. |
@DELETE | Indicates that the following method will answer to an HTTP DELETE request. |
@Produces(MediaType.TEXT_PLAIN[, more-types]) | @Produces defines which MIME type is delivered by a method annotated with @GET. In the example text (“text/plain”) is produced. Other examples would be “application/xml” or “application/json”. |
@Consumes(type[, more-types]) | @Consumes defines which MIME type is consumed by this method. |
@PathParam | Used to inject values from the URL into a method parameter. This way you inject, for example, the ID of a resource into the method to get the correct object. |
可以從 eclipse 官方網站 直接下載 Eclipse IDE for Java EE Developers,裡面已經包含 Java EE 開發時需要的套件了
若是已經有安裝 Eclipse IDE for Java Developers 的話,則可以參考Java web development with Eclipse WTP 從 Eclipse 中直接安裝以下套件
Help > Install New Software > Work with 選擇 Neon - http://download.eclipse.org/releases/neon (各版本路徑基本上就版本號差異)
Web, XML, Java EE Developmentand OSGi
這邊以 Apache Tomcat 為例
Eclipse 允許在 IDE 中直接下載並啟動 local Tomcat
Window > Preferences > Server > Runtime Environments
有些版本會有 Download and Install 可選,這時只要指定好資料夾, Eclipse 會自動將 Tomcat 下載到指定資料夾
接著再將 Tomcat installation directory 選到剛剛裝好 Tomcat 的資料夾,這樣 eclipse 就可以在程式執行時到該路徑去啟動 Tomcat 了
另外若你選擇的版本沒有 Download and Install 可以按,那可以到 Tomcat 官方網站 去下載檔案,解壓縮到自己想要的目錄
之後一樣將 Tomcat installation directory 選到剛剛裝好 Tomcat 的資料夾也可以
Manual setup of Jersey libraries in an Eclipse project
下載 Jersey: Jersey download site
壓縮檔內包含了 Jersey implementation JAR 和相關的 core dependencies
解壓縮後將所有 JARs 檔複製到 Dynamic Web Project 中的 WEB-INF/lib
資料夾
Create a new Dynamic Web Project called xyz.kshuang.jersey.first
勾選 Generate web.xml deployment descriptor
接著依照 0x05 Installation of Jersey,將 jar 檔放進來
範例程式
package xyz.kshuang.jersey.hello; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; // Plain old Java Object it does not extend as class or implements // an interface // The class registers its methods for the HTTP GET request using the @GET annotation. // Using the @Produces annotation, it defines that it can deliver several MIME types, // text, XML and HTML. // The browser requests per default the HTML MIME type. //Sets the path to base URL + /hello @Path("/hello") public class Hello { // This method is called if TEXT_PLAIN is request @GET @Produces(MediaType.TEXT_PLAIN) public String sayPlainTextHello() { return "Hello Jersey"; } // This method is called if XML is request @GET @Produces(MediaType.TEXT_XML) public String sayXMLHello() { return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>"; } // This method is called if HTML is request @GET @Produces(MediaType.TEXT_HTML) public String sayHtmlHello() { return "<html> " + "<title>" + "Hello Jersey" + "</title>" + "<body><h1>" + "Hello Jersey" + "</body></h1>" + "</html> "; } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>xyz.kshuang.jersey.hello</display-name> <!-- Register resources and providers under xyz.kshuang.jersey.hello package. --> <servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>xyz.kshuang.jersey.hello</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <!-- Register resources and providers under xyz.kshuang.jersey.hello package. --> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>