歡迎來到Java的Restful Web服務教程。REST是代表狀態轉換(REpresentational State Transfer)的首字母縮寫。REST是一種用於開發可通過網絡訪問的應用程序的架構風格。REST架構風格是由羅伊·費爾丁在他於2000年的博士論文中提出的。
Restful Web服務
Restful Web服務是一種無狀態的客戶端-服務器架構,其中Web服務是資源,可以通過其URI進行識別。REST客戶端應用程序可以使用HTTP GET/POST方法來調用Restful Web服務。REST不指定任何特定的協議來使用,但在幾乎所有情況下都是使用HTTP/HTTPS。與SOAP Web服務相比,這些服務輕量級,並且不遵循任何標準。我們可以使用XML、JSON、文本或任何其他類型的數據進行請求和響應。
Java RESTful Web服務API
Java API for RESTful Web Services (JAX-RS)是用於創建REST Web服務的Java API。JAX-RS使用註釋來簡化Web服務的開發和部署。JAX-RS是JDK的一部分,因此您無需包含任何內容來使用其註釋。
Restful Web Services Annotations
一些重要的 JAX-RS 注解包括:
@Path
:用於指定類和方法的相對路徑。通過掃描 Path 注解值,我們可以獲得 Web 服務的 URI。@GET
、@PUT
、@POST
、@DELETE
和@HEAD
:用於指定方法的 HTTP 請求類型。@Produces
、@Consumes
:用於指定請求和響應類型。@PathParam
:用於通過解析將方法參數綁定到路徑值。
Restful Web Services and SOAP
- SOAP 是一種協議,而 REST 是一種架構風格。
- SOAP 服務器和客戶端應用程序緊密耦合並與 WSDL 合同綁定,而 REST Web 服務和客戶端則沒有合同。
- 與 SOAP Web 服務相比,REST Web 服務的學習曲線更容易。
- REST Web 服務的請求和響應類型可以是 XML、JSON、文本等,而 SOAP 僅使用 XML。
- JAX-RS 是用於 REST web 服務的 Java API,而 JAX-WS 是用於 SOAP web 服務的 Java API。
REST API 實現
有兩個主要的 JAX-RS API 實現。
- Jersey: Jersey 是 Sun 提供的參考實現。要將 Jersey 用作我們的 JAX-RS 實現,我們只需在 web.xml 中配置其 servlet 並添加所需的依賴項。請注意,JAX-RS API 是 JDK 的一部分,而不是 Jersey,因此我們必須在應用程序中添加其依賴項 jars。
- RESTEasy: RESTEasy 是提供 JAX-RS 實現的 JBoss 項目。
Java Restful Web Services 教程
讓我們看看使用 Jersey 和 RESTEasy 創建 Restful web 服務有多簡單。我們將在 HTTP 上公開以下方法,並使用 Chrome Postman 擴展來測試這些方法。
URI | HTTP Method | Description |
---|---|---|
/person/{id}/getDummy | GET | Returns a dummy person object |
/person/add | POST | Adds a person |
/person/{id}/delete | GET | Delete the person with ‘id’ in the URI |
/person/getAll | GET | Get all persons |
/person/{id}/get | GET | Get the person with ‘id’ in the URI |
Jersey Restful Web Services
建立動態 Web 專案,然後將其轉換為 Maven,以獲取 Web 服務專案的框架。下圖顯示最終專案的項目結構。 讓我們來看看 pom.xml 檔案中我們擁有的 Jersey 依賴項。
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>JAXRS-Example</groupId>
<artifactId>JAXRS-Example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
我們不需要添加 jersey-client 依賴項,但如果您正在編寫 Java 程式來調用使用 Jersey 的 REST Web 服務,則需要它。現在讓我們來看看部署描述符,以了解如何配置 Jersey 來建立我們的 Web 應用程式。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>JAXRS-Example</display-name>
<!-- Jersey Servlet configurations -->
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.journaldev</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Jersey Servlet configurations -->
</web-app>
這就是將 Jersey 插入到我們的 Web 應用程式中所需的全部,在我們的 Java 程式碼中,我們將使用 JAX-RS 標註。請注意初始參數 com.sun.jersey.config.property.packages
的值,以提供將被掃描以尋找 Web 服務資源和方法的套件。
REST 範例模型類別
首先,我們將創建兩個模型 Bean – Person
用於我們的應用程式資料和 Response
用於向客戶端系統發送響應。由於我們將發送 XML 響應,因此 Bean 應該被標註為 @XmlRootElement
,因此我們有這個類別。
package com.journaldev.jaxrs.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement (name="person")
public class Person {
private String name;
private int age;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString(){
return id+"::"+name+"::"+age;
}
}
package com.journaldev.jaxrs.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Response {
private boolean status;
private String message;
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
REST Web Services 教程服務
根據我們的URI結構,以下是服務接口及其實現代碼。
package com.journaldev.jaxrs.service;
import com.journaldev.jaxrs.model.Person;
import com.journaldev.jaxrs.model.Response;
public interface PersonService {
public Response addPerson(Person p);
public Response deletePerson(int id);
public Person getPerson(int id);
public Person[] getAllPersons();
}
package com.journaldev.jaxrs.service;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.journaldev.jaxrs.model.Person;
import com.journaldev.jaxrs.model.Response;
@Path("/person")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class PersonServiceImpl implements PersonService {
private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
@Override
@POST
@Path("/add")
public Response addPerson(Person p) {
Response response = new Response();
if(persons.get(p.getId()) != null){
response.setStatus(false);
response.setMessage("Person Already Exists");
return response;
}
persons.put(p.getId(), p);
response.setStatus(true);
response.setMessage("Person created successfully");
return response;
}
@Override
@GET
@Path("/{id}/delete")
public Response deletePerson(@PathParam("id") int id) {
Response response = new Response();
if(persons.get(id) == null){
response.setStatus(false);
response.setMessage("Person Doesn't Exists");
return response;
}
persons.remove(id);
response.setStatus(true);
response.setMessage("Person deleted successfully");
return response;
}
@Override
@GET
@Path("/{id}/get")
public Person getPerson(@PathParam("id") int id) {
return persons.get(id);
}
@GET
@Path("/{id}/getDummy")
public Person getDummyPerson(@PathParam("id") int id) {
Person p = new Person();
p.setAge(99);
p.setName("Dummy");
p.setId(id);
return p;
}
@Override
@GET
@Path("/getAll")
public Person[] getAllPersons() {
Set<Integer> ids = persons.keySet();
Person[] p = new Person[ids.size()];
int i=0;
for(Integer id : ids){
p[i] = persons.get(id);
i++;
}
return p;
}
}
大部分代碼都是自解釋的,花點時間熟悉 JAX-RS 注釋 @Path
、@PathParam
、@POST
、@GET
、@Consumes
和 @Produces
。
Restful Web Services 測試
就是這樣。我們的 Web 服務已經準備就緒,只需將其導出為 WAR 檔案並放入 Tomcat webapps 目錄,或部署到您選擇的任何其他容器中。以下是使用 Postman Chrome 擴展為此 Web 服務執行的一些測試。請注意,在下面的圖像中,我們必須在請求標頭中提供 Accept 和 Content-Type 值為“application/xml”。
這就是使用Jersey JAX-RS實現Web服務的所有內容。如您所見,大部分代碼都使用了JAX-RS標註,Jersey是通過部署描述符和依賴插入的。
RESTEasy RESTful Web Services Example
我們將使用在Jersey專案中開發的所有業務邏輯,但不是對同一專案進行更改,我已經創建了一個新專案。創建一個動態Web專案並將其轉換為Maven專案。然後複製所有Java類 – Person、Response、PersonService和PersonServiceImpl。以下是在完成所有更改後的最終專案。在pom.xml文件中添加以下RESTEasy依賴項。
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.13.Final</version>
</dependency>
以下是我們正在配置Resteasy servlet的web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>JAXRS-Example-RestEasy</display-name>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.journaldev.jaxrs.resteasy.app.MyApp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
請注意,我們在init-param中提供了`MyApp`類作為值,在這裡我們擴展了`javax.ws.rs.core.Application`類,如下所示。
package com.journaldev.jaxrs.resteasy.app;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
import com.journaldev.jaxrs.service.PersonServiceImpl;
public class MyApp extends Application {
private Set<Object> singletons = new HashSet<Object>();
public MyApp() {
singletons.add(new PersonServiceImpl());
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
RESTEasy Web Services Test
就是這樣。我們的Web服務已經準備好使用RESTEasy JAX-RS實現。以下是一些來自Postman Chrome擴展測試的輸出。
這就是關於Restful Web Services 教程的所有內容,我希望你了解了 JAX-RS 標註的重要性,並明白了擁有標準 API 的好處,這有助於我們重用代碼,並輕鬆從 Jersey 轉移到 RESTEasy。
Source:
https://www.digitalocean.com/community/tutorials/restful-web-services-tutorial-java