
第3章 开发 REST/Web 应用
3.1 编写REST JSON服务
本案例将说明如何在Quarkus 框架中通过REST服务使用和返回JSON数据。
3.1.1 案例简介
本案例介绍基于 Quarkus 框架实现 REST 的基本功能。Quarkus 框架的 REST 实现遵循JAX-RS 规范,浏览器和服务器之间的数据传输格式采用 JSON。该模块引入了RESTEasy/JAX-RS和 JSON-B扩展。通过阅读和分析在 Web上实现查询、新增、删除、修改数据的操作等案例代码,可以理解和掌握基于Quarkus 框架的REST服务用法。
基础知识:JAX-RS规范和RESTEasy框架。
JAX-RS 规范(Java API for RESTful Web Services)是一套用 Java 实现 REST 服务的规范,也是一个 Java 编程语言的应用程序接口,支持按照表述性状态转移(REST)架构风格创建 Web服务。JAX-RS规范提供了一些注解来说明资源类,并把 POJO Java类封装成 Web资源。JAX-RS规范的常用注解说明如表3-1所示。
表3-1 JAX-RS规范的常用注解说明

续表

目前实现 JAX-RS 规范的框架包括 Apache CXF、Jersey、RESTEasy、Restlet、Apache Wink等。
本案例会用到的 RESTEasy 是 JBoss/Red Hat 的一个开源项目,其提供各种框架来帮助构建RESTful Web Services和RESTful Java应用程序。RESTEasy遵循JAX-RS规范,是Jakarta RESTful Web服务的一个完整实现且可通过 JCP认证。RESTEasy与 JBoss应用服务器能很好地集成在一起。RESTEasy还提供了一个RESTEasy JAX-RS客户端调用框架,能够很方便地与EJB、Seam、Guice、Spring 和 Spring MVC 集成使用,支持在客户端与服务端自动实现 Gzip解压缩。此外,RESTEasy还实现了MicroProfile客户端规范API。
3.1.2 编写程序代码
编写程序代码有 3种方式。第 1种方式是通过代码 UI来实现的,在 Quarkus 官网的生成代码页面中按照指定步骤生成脚手架代码,然后下载文件,将项目引入 IDE 工具中,最后修改程序源码。
第2种方式是通过mvn来构建程序,通过下面的命令创建Maven项目来实现:

在IDE工具中导入Maven工程项目,然后增加和修改程序源码。
第3种方式是直接从GitHub上获取代码,可以从GitHub上克隆预先准备好的示例代码:

该程序位于“020-quarkus-sample-rest-json”目录中,是一个Maven工程项目程序。
在IDE工具中导入Maven工程项目程序,图3-1是一个典型的Maven工程项目结构。

图3-1 quarkus-sample-rest-json的目录结构图
程序引入了Quarkus 的两项扩展依赖性,在pom.xml的<dependencies>下有如下内容:

quarkus-resteasy是Quarkus 整合了RESTEasy的REST服务实现。而quarkus-resteasy-jsonb是Quarkus 整合了RESTEasy的JSON解析实现。
quarkus-sample-rest-json程序的应用架构(见图3-2)表明,外部访问ProjectResource资源接口,ProjectResource调用ProjectService服务,ProjectResource资源依赖于RESTEasy框架。quarkus-sample-rest-json程序的核心类如表3-2所示。

图3-2 quarkus-sample-rest-json程序应用架构图
表3-2 quarkus-sample-rest-json程序的核心类

下面讲解 quarkus-sample-rest-json程序中的 ProjectResource资源类、ProjectService服务类和Project实体类的功能和作用。
1.ProjectResource资源类
用 IDE工具打开 com.iiit.quarkus.sample.rest.json.ProjectResource类文件,该类主要实现了外部JSON接口的调用,其代码如下:


程序说明:
①ProjectResource类的作用还是与外部进行交互,@Path("/projects")表示路径。
②@Produces(MediaType.APPLICATION_JSON)表示生成的数据格式是 MediaType.APPLICATION_JSON格式。
③@Consumes(MediaType.APPLICATION_JSON)表示消费的数据格式是 MediaType.APPLICATION_JSON格式。
④ ProjectResource 类的主要方法是 REST 的基本操作方法,包括 GET、POST、PUT 和DELETE方法。
2.ProjectService服务类
用IDE工具打开com.iiit.quarkus.sample.rest.json.ProjectService类文件,ProjectService类主要是给ProjectResource提供业务逻辑服务,其代码如下:


程序说明:
①ProjectService服务类内部有一个变量Set<Project>,用来存储所有的Project对象实例。
②ProjectService服务实现了对Set<Project>的显示、查询、新增、修改和删除等操作功能。
3.Project实体类
用 IDE 工具打开 com.iiit.quarkus.sample.rest.json.Project 类文件,实体类主要是基本的POJO对象,其代码如下:

程序说明:Project类是一个实体类,但它不是一个标准的JavaBean。
该程序动态运行的序列图(如图 3-3 所示,遵循 UML 2.0 规范绘制)描述了外部调用者Actor、ProjectResource和ProjectService等3个对象之间的时间顺序交互关系。

图3-3 quarkus-sample-rest-json程序动态运行的序列图
该序列图中总共有5个序列,分别介绍如下。
序列 1活动:① 外部调用 ProjectResource资源类的 GET(list)方法;② GET(list)方法调用ProjectService服务类的list方法;③返回整个Project列表。
序列2活动:① 外部传入参数ID并调用ProjectResource资源类的GET(getById)方法;② GET(getById)方法调用ProjectService服务类的getById方法;③ 返回Project列表中对应ID的Project对象。
序列 3活动:① 外部传入参数 Project对象并调用 ProjectResource资源类的 POST(add)方法;②POST(add)方法调用ProjectService服务类的add方法,ProjectService服务类实现增加一个Project对象的操作并返回整个Project列表。
序列4活动:① 外部传入参数Project对象并调用ProjectResource资源类的PUT(update)方法;② PUT(update)方法调用ProjectService服务类的update方法,ProjectService服务类根据项目名称是否相等来实现修改一个Project对象的操作并返回整个Project列表。
序列 5 活动:① 外部传入参数 Project 对象并调用 ProjectResource 资源类的DELETE(delete)方法;② DELETE(delete)方法调用 ProjectService 服务类的 delete 方法,ProjectService 服务类根据项目名称是否相等来实现删除一个 Project 对象的操作并返回整个Project列表。
3.1.3 验证程序
通过下列几个步骤(如图3-4所示)来验证案例程序。

图3-4 quarkus-sample-rest-json程序验证流程图
下面对其中涉及的关键点进行说明。
1.启动quarkus-sample-rest-json程序服务
启动程序有两种方式,第 1种是在开发工具(如 Eclipse)中调用 ProjectMain类的 run方法,第2种是在程序目录下直接运行命令mvnw compile quarkus:dev。
2.通过API显示全部Project的JSON列表内容
为获取所有Project信息,在命令行窗口中键入命令curl http://localhost:8080/projects。程序会返回所有Project的JSON列表。
3.通过API获取一条Project数据
为获取一条Project数据,在命令行窗口中键入命令curl http://localhost:8080/projects/1。其返回项目ID为1的JSON列表。
4.通过API增加一条Project数据
按照JSON格式增加一条Project数据,命令行窗口中的命令如下:

或

注意:这里采用的是 Windows上的 JSON格式。由于 curl命令在 Windows和 Linux上的JSON格式有所不同,主要区别在带有引号的内容上。如果是在Linux上,这一命令的JSON格式如下:

5.通过API修改一条Project数据
按照JSON格式修改一条Project数据,命令行窗口中的命令如下:

根据结果,可以看到已经对项目C的描述进行了修改。6.通过API删除一条Project数据
按照JSON格式删除一条Project数据,命令行窗口中的命令如下:

根据结果,可以看到已经删除了项目C的内容。
3.1.4 Quarkus 的Web实现原理讲解
Quarkus 框架使用Eclipse Vert.x作为基本HTTP层来实现Web功能。这不同于Spring Boot框架内嵌和集成Tomcat。Quarkus 框架也支持Servlet功能,Quarkus 框架的Servlet功能实现是使用运行在 Vert.x 之上的 Undertow 软件。RESTEasy 只支持 JAX-RS 规范。如果存在Undertow,RESTEasy 将作为 Servlet 过滤器运行,否则它将直接运行在 Vert.x 上,而不涉及Servlet。Quarkus 框架的Web架构图如图3-5所示。

图3-5 Quarkus 框架的Web架构图
下面对Quarkus 框架的Web原理进行说明。假设传入了一个HTTP请求,Eclipse Vert.x的HTTP 服务器接收请求,然后将其路由到应用程序。如果请求的目标是 JAX-RS 资源,那么路由层将调用工作线程中的 resource 方法,并在数据可用时返回响应。图 3-6 描述了 Quarkus 的We b调用过程。

图3-6 Quarkus 的Web调用过程图
同时,Quarkus 框架也支持响应式Web的调用,这将在第7章中进行详细讲解。