嵌入式 Jetty 的 Jersey JAX-RS CRUD Rest Web服务

 在本教程中,我们将学习如何使用Jetty  和 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 请求

什么是 Jetty?

Jetty是一个开源、基于标准、全功能实现的JAVA服务器。它在Apache2.0协议下发布,因此可以自由的用于商业用途和发行。首创于1995年,Jetty受益于一个广大的用户社区,有一个稳定的核心开发者来持续专著的开发。有很多正在运行的使用Jetty的例子,这也不过是千分之十的Jetty实例。 虽然Jetty的目标很低调, 无数的站点和产品使用Jetty,但是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)参考实现。

在本教程中,我们使用 Jetty服务器来部署 Jersey Web 应用程序。

使用的工具和技术

  • JDK 1.8 或更高版本
  • Maven 3.5+
  • NetBeans IDE
  • JAX-RS 2.0 +
  • Jetty 
  • Jersey 
  • Tomcat 8.5+

开发步骤

  1. 在 IDE 中创建一个 Maven 项目
  2. 添加 Maven 依赖项
  3. 项目结构
  4. 创建用户模型类
  5. 创建一个用户服务类
  6. 创建一个 UserResource 类
  7. 创建应用程序类
  8. REST API 的客户端
  9. 结论

1.在IDE中创建一个Maven 项目

2.添加maven依赖

这是完整的 Maven pom.xml 文件。它包含依赖项。

<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>com.zetcode</groupId>
    <artifactId>JerseyJettyEx</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>JerseyJettyEx</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>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>9.4.0.v20161208</version>
        </dependency>



        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.4.0.v20161208</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.4.0.v20161208</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>JerseyJettyEx</finalName>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.5.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.example.jaxrs.app.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3、项目结构

有关项目结构和打包结构,请参阅下面的屏幕截图:

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. 创建应用类

让我们创建一个应用程序类。

package com.example.jaxrs.app;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.servlet.ServletContainer;

public class Main {

    public static void main(String[] args) {

        Server server = new Server(8080);

        ServletContextHandler ctx
                = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);

        ctx.setContextPath("/");
        server.setHandler(ctx);

        ServletHolder serHol = ctx.addServlet(ServletContainer.class, "/restapi/*");
        serHol.setInitOrder(1);
        serHol.setInitParameter("jersey.config.server.provider.packages",
                "com.example.jaxrs.resource");

        try {
            server.start();
            server.join();
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } finally {

            server.destroy();
        }
    }
}

8. REST API 客户端

 这是完整的 Maven pom.xml 文件。它包含依赖项。

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>


import com.example.jaxrs.model.User;
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;

public class UserResourceMain {

    private static final String FULL_PATH = "http://localhost:8080/restapi/users";

    public static void main(String[] args) {
        UserResourceMain urm = new UserResourceMain();
        urm.testListAllUsers();
        urm.testGetUser();
        urm.testCreateUser();
        urm.testUpdateUser();
        urm.testDeleteUser();
    }

    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);
    }

    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();
    }

    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();
    }

    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();
    }

    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);
    }

}

9.创建可运行单文件jar包

编辑pom.xml

<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>com.zetcode</groupId>
    <artifactId>JerseyJettyEx</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>JerseyJettyEx</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>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>9.4.0.v20161208</version>
        </dependency>



        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.4.0.v20161208</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.4.0.v20161208</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>JerseyJettyEx</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.1</version>

                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.example.jaxrs.app.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>

                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>

            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.5.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.example.jaxrs.app.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

重新build,在target目录下生成JerseyJettyEx-jar-with-dependencies.jar

命令行下运行:

java -jar JerseyJettyEx-jar-with-dependencies.jar


2022-03-23 16:44:31.319:INFO::main: Logging initialized @160ms to org.eclipse.jetty.util.log.StdErrLog
2022-03-23 16:44:31.383:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT
2022-03-23 16:44:32.573:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@61fe30{/,null,AVAILABLE}
2022-03-23 16:44:32.801:INFO:oejs.AbstractConnector:main: Started ServerConnector@3a17fcb8{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2022-03-23 16:44:32.803:INFO:oejs.Server:main: Started @1646ms

结论

在本教程中,我们使用 jetty和 Jersey创建了一个 CRUD RESTFul 应用程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值