1. 簡介
JAX-RS (Java API for RESTful Web Services) 是一套 Java API,提供在創建 RESTful Web Services 的支持。 該框架充分利用註解來簡化這些 API 的開發和部署。
在本教程中,我們將使用 JBoss 提供的 RESTEasy,作為 JAX-RS 規範的可移植實現,以創建簡單的 RESTful Web 服務。
2. 項目設置
我們將考慮兩種可能的情況:
- 獨立設置 – 適用於每個應用程序服務器
- JBoss AS 設置 – 僅用於在 JBoss AS 上部署
2.1. 獨立設置
讓我們從使用 JBoss WildFly 10 和獨立設置開始。
JBoss WildFly 10 隨附了 RESTEasy 版本 6.2.9.Final,但正如你將看到的那樣,我們將使用 pom.xml 配置為使用 6.2.9.Final 版本。
並且,由於 resteasy-servlet-initializer,RESTEasy 通過 ServletContainerInitializer 接口提供與獨立 Servlet 3.0 容器的集成。
讓我們查看 pom.xml
<properties>
<resteasy.version>6.2.9.Final</resteasy.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${resteasy.version}</version>
</dependency>
</dependencies>
jboss-deployment-structure.xml
在 JBoss 中,部署為 WAR、JAR 或 EAR 的所有內容都是模塊。這些模塊被稱為 動態模塊。
除了這些之外,還有一些靜態 模塊,位於 $JBOSS_HOME/modules。由於 JBoss 具有 RESTEasy 的 靜態模塊 – 用於獨立部署,因此 jboss-deployment-structure.xml 在排除其中一些方面是必不可少的。
這樣,包含在我們的 WAR 文件中的所有類和 JAR 文件都將被加載:
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="resteasy" />
</exclude-subsystems>
<exclusions>
<module name="javaee.api" />
<module name="jakarta.ws.rs.api"/>
<module name="org.jboss.resteasy.resteasy-jaxrs" />
</exclusions>
<local-last value="true" />
</deployment>
</jboss-deployment-structure>
2.2. JBoss 作為設置
如果您要使用 JBoss 版本 6 或更高版本運行 RESTEasy,您可以選擇採用應用程序服務器中已包含的庫,從而簡化 pom:
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>${resteasy.version}</version>
</dependency>
</dependencies>
請注意,jboss-deployment-structure.xml 不再需要。
3. Server Side Code
3.1. Servlet Version 3web.xml
現在讓我們快速查看我們簡單項目的 web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>RestEasy Example</display-name>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
</web-app>
resteasy.servlet.mapping.prefix 僅在你想要為 API 應用程序添加前綴的相對路徑時才需要。
此時,我們尚未聲明任何 Servlet 在 web.xml 中,因為 resteasy servlet-initializer 已作為依賴項添加到 pom.xml 中。這是因為 RESTEasy 提供 org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer 類,該類實現了 jakarta.server.ServletContainerInitializer。
ServletContainerInitializer 是一個初始化器,並在任何 Servlet 上下文準備就緒之前執行——你可以使用此初始化器來定義應用程序的 Servlet、過濾器 或 監聽器。
3.2. The Application Class
jakarta.ws.rs.core.Application 類是一個標準的 JAX-RS 類,你可以實現它來提供有關部署的信息:
@ApplicationPath("/rest")
public class RestEasyServices extends Application {
private Set<Object> singletons = new HashSet<Object>();
public RestEasyServices() {
singletons.add(new MovieCrudService());
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
如你所見——這是一個簡單類,列出了所有 JAX-RS 根資源和提供程序,並且它已使用 @ApplicationPath 標註。
如果對於類和單例集返回一個空集,則 WAR 將掃描 JAX-RS 註解資源和提供程序類。
3.3. A Services Implementation Class
最後,讓我們查看實際的 API 定義:
@Path("/movies")
public class MovieCrudService {
private Map<String, Movie> inventory = new HashMap<String, Movie>();
@GET
@Path("/getinfo")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Movie movieByImdbId(@QueryParam("imdbId") String imdbId) {
if (inventory.containsKey(imdbId)) {
return inventory.get(imdbId);
} else {
return null;
}
}
@POST
@Path("/addmovie")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response addMovie(Movie movie) {
if (null != inventory.get(movie.getImdbId())) {
return Response
.status(Response.Status.NOT_MODIFIED)
.entity("Movie is Already in the database.").build();
}
inventory.put(movie.getImdbId(), movie);
return Response.status(Response.Status.CREATED).build();
}
}
4. 結論
在本快速教程中,我們介紹了 RESTEasy 並使用它構建了一個超級簡單的 API。