在本教程中,我们将学习如何使用 RESTEasy 和 Jersey 创建 JAX-RS Get、POST、PUT 和 DELETE Rest Web 服务。
我们将建造什么?
我们正在构建一个简单的?用户管理应用程序,它具有以下 CRUD Rest API。?
为用户?资源?创建了以下五个 REST API(控制器处理程序方法)? 。
在开始之前,我想给你一个 JAX-RS Java API 的概述。
什么是 JAX-RS?
JAX-RS(用于 RESTful Web 服务的 Java API)?是一组 Java API,为创建 REST API 提供支持。并且该框架很好地利用了 JAX-RS 注解来简化这些 API 的开发和部署。
JAX-RS 2.0 (JSR-339)?和?JAX-RS 2.1 (JSR-370)?是 JCP(Java 社区进程)规范,它们通过 HTTP 协议为 RESTful Web 服务提供 Java API。
一些比较知名的 JAX-RS API 实现是 RESTEasy 和 Jersey。
JAX-RS HTTP 注释
JAX-RS 具有响应 HTTP 请求的注释。
- @GET??- 表示注解的方法响应 HTTP GET 请求
- @POST??- 表示被注解的方法响应一个 HTTP POST 请求
- @DELETE??- 表示注解的方法响应 HTTP DELETE 请求
- @PUT??- 表示注解的方法响应 HTTP PUT 请求
什么是 RESTEasy?
RESTEasy?是一个用于开发 RESTful Web 服务的 Java 框架。它是 JAX-RS 2.0 规范的完全认证且可移植的实现。
RESTEasy?提供与 JBoss 应用服务器更紧密的集成,但我们可以将它部署在任何 servlet 容器上,如 Tomcat、Jetty 等。
什么是 Jersey??
Jersey?RESTful Web Services,前身为
Glassfish Jersey,目前 Eclipse?
Jersey框架是一个开源框架,用于在 Java 中开发 RESTful Web Services。它提供对 JAX-RS API 的支持并用作 JAX-RS(JSR 311 & JSR 339 & JSR 370)参考实现。
在本教程中,我们使用 tomcat 服务器来部署 RESTEasy 或
Jersey?
Web 应用程序。
使用的工具和技术
- JDK 1.8 或更高版本
- Maven 3.5+
- NetBeans IDE
- JAX-RS 2.0 +
- RESTEasy?
- Jersey?
- Tomcat 8.5+
开发步骤
- 在 IDE 中创建一个 Maven Web 项目
- 添加 Maven 依赖项
- 项目结构
- 创建用户模型类
- 创建一个用户服务类
- 创建一个 UserResource 类
- 创建应用程序类
- REST API 的客户端
- 结论
2.添加maven依赖
这是完整的 Maven pom.xml 文件。它包含依赖项。
RESTEasy:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>RESTEasyContext</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>RESTEasyContext</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Set up RESTEasy-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.15.3.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>3.15.3.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.15.3.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Jersey:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>JerseyContext</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>JerseyContext</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
3、项目结构
有关项目结构和打包结构,请参阅下面的屏幕截图:
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/jaxrs-crud-example"/>
4.创建用户模型类
这是一个?用户?模型类。它包含三个属性:??id、??name和?email。
package com.example.jaxrs.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
private Long id;
private String name;
private String email;
public User() {
}
public User(Long id, String name, String email) {
super();
this.id = id;
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", email=" + email + "]";
}
}
5.创建一个UserService类
让我们创建??为用户对象提供内存存储?的UserService 。UserService?包含 CRUD 合约方法。我们有查找用户、保存用户、更新使用和删除用户的方法。
package com.example.jaxrs.service;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.NotFoundException;
import com.example.jaxrs.model.User;
public class UserService {
private List< User> users = new ArrayList< User>();
public List< User> findAll() {
users.add(new User(100L,
"Ramesh", "ramesh@gmail.com"));
users.add(new User(101L,
"Tny", "tony@gmail.com"));
users.add(new User(102L,
"Tom", "tom@gmail.com"));
return users;
}
public User fetchBy(long id) throws NotFoundException {
for (User user : findAll()) {
if (id == user.getId()) {
return user;
} else {
throw new NotFoundException("Resource not found with Id :: " + id);
}
}
return null;
}
public boolean create(User user) {
return users.add(user);
}
public boolean update(User user) {
for (User updateUser : users) {
if (user.getId().equals(updateUser.getId())) {
users.remove(updateUser);
users.add(user);
return true;
}
}
return false;
}
public boolean delete(Long id) throws NotFoundException {
for (User user : users) {
if (user.getId().equals(id)) {
users.remove(user);
return true;
}
}
return false;
}
}
6.创建UserResource类
最后,让我们在这里查看一个实际的 CRUD API 定义:
package com.example.jaxrs.resource;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.example.jaxrs.model.User;
import com.example.jaxrs.service.UserService;
/**
* CRUD Rest APIs for User Resource
*
* @author Ramesh Fadatare
*
*/
@Path("users")
public class UserResource {
private UserService userService = new UserService();
@GET
@Produces(MediaType.APPLICATION_JSON)
// @Produces(MediaType.TEXT_PLAIN)
public Response getUsers() {
List< User> users = userService.findAll();
if (!users.isEmpty()) {
return Response.ok(users).build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getUserById(@PathParam("id") Long id) {
User user = userService.fetchBy(id);
if (user.getId() != null) {
return Response.ok(user).build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
boolean result = userService.create(user);
if (result) {
return Response.ok().status(Response.Status.CREATED).build();
} else {
return Response.notModified().build();
}
}
@PUT
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateUser(@PathParam("id") long id, User user) {
boolean result = userService.update(user);
if (result) {
return Response.ok().status(Response.Status.NO_CONTENT).build();
} else {
return Response.notModified().build();
}
}
@Path("/{id}")
@DELETE
@Produces(MediaType.APPLICATION_JSON)
public Response deleteUser(@PathParam("id") Long id) {
boolean result = userService.delete(id);
if (result) {
return Response.ok().status(Response.Status.NO_CONTENT).build();
} else {
return Response.notModified().build();
}
}
}
让我们从上面的代码中理解 JAX-RS 注解:
- @Path?注释指定资源响应的 URL?。?
- @GET??注解表示被注解的方法响应 HTTP GET 请求。
- @Produces?注释用于指定资源可以生成并发送回客户端的 MIME 媒体类型。?
- 创建新资源时,我们使用?@POST?注解。
- @Consumes??注释用于指定资源可以从客户端接受或使用的表示的 MIME 媒体类型。
7. 创建应用类
让我们创建一个应用程序配置类。应用程序定义 JAX-RS 应用程序的组件并提供额外的元数据。javax.ws.rs.core.Application?类?是一个标准的 JAX-RS 类,您可以实现它以提供有关您的部署的信息:
package com.example.jaxrs.conf;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import com.example.jaxrs.resource.UserResource;
@ApplicationPath("/restapi")
public class ApplicationConfig extends Application {
private Set< Object> singletons = new HashSet< Object>();
public ApplicationConfig() {
singletons.add(new UserResource());
}
@Override
public Set< Object> getSingletons() {
return singletons;
}
}
请注意,使用?@ApplicationPath?注释,我们将路径设置为 RESTful Web 服务。
8. REST API 的 RESTEasy 客户端
?这是完整的 Maven pom.xml 文件。它包含依赖项。
RESTEasy:
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.javaguides</groupId>
<artifactId>RESTEasyClientRESTAPI</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>RESTEasyClientRESTAPI</name>
<url>http://maven.apache.org</url>
<properties>
<resteasy.version>3.9.3.Final</resteasy.version>
</properties>
<dependencies>
<!-- Set up RESTEasy -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
<!-- RESTEasy Client Dependency -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<finalName>resteasy-crud-example-tutorial</finalName>
</build>
</project>
Jersey:
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.javaguides</groupId>
<artifactId>JerseyClientRESTAPI</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>JerseyClientRESTAPI</name>
<url>http://maven.apache.org</url>
<properties>
<resteasy.version>3.9.3.Final</resteasy.version>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.35</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<finalName>resteasy-crud-example-tutorial</finalName>
</build>
</project>
package net.javaguides.resteasy;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import org.junit.Test;
import net.javaguides.resteasy.model.User;
public class UserResourceMain {
private static final String FULL_PATH = "http://localhost:8080/jaxrs-crud-example/restapi/users";
public static void main(String[] args) {
UserResourceMain urm = new UserResourceMain();
urm.testListAllUsers();
urm.testGetUser();
}
@Test
public void testListAllUsers() {
Client client = ClientBuilder.newClient();
final WebTarget target = client
.target(FULL_PATH);
String response = target.request().get(String.class);
System.out.println(response);
}
@Test
public void testGetUser() {
Client client = ClientBuilder.newClient();
final WebTarget target = client
.target(FULL_PATH + "/100");
Response response = target.request().get();
User user = response.readEntity(User.class);
System.out.println(user.toString());
response.close();
}
@Test
public void testCreateUser() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(FULL_PATH);
Response response = target.request()
.post(Entity.entity(new User(100L,
"Amir", "amir@gmail.com"), "application/json"));
System.out.println(response.getStatus());
response.close();
}
@Test
public void testUpdateUser() {
User user = new User();
user.setName("Ram");
user.setEmail("ram@gmail.com");
Client client = ClientBuilder.newClient();
WebTarget target = client.target(FULL_PATH + "/100");
Response response = target.request()
.put(Entity.entity(user, "application/json"));
System.out.println(response.getStatus());
response.close();
}
@Test
public void testDeleteUser() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(FULL_PATH + "/101");
Response response = target.request()
.delete();
System.out.println(response.getStatus());
response.close();
final WebTarget target1 = client
.target(FULL_PATH);
String response1 = target1.request().get(String.class);
System.out.println(response1);
}
}
结论
在本教程中,我们使用 RESTEasy
和 Jersey
创建了一个 CRUD RESTFul 应用程序。该应用程序部署在 Tomcat 上。
|