编辑此页面

迁移到 Quarkus REST(以前称为 RESTEasy Reactive)

在大多数情况下,从 RESTEasy Classic 迁移到 Quarkus REST(原 RESTEasy Reactive)是一个直接的过程,但是有少数情况需要一些注意。本文档列出了尝试迁移的用户应该了解的问题。

Quarkus REST 的参考文档可以在 此处找到。

服务器

Quarkus REST(quarkus-rest 及其依赖项)的服务器部分实现了 Jakarta REST 规范,但利用了 Quarkus 的构建时处理以及 Vert.x 提供的统一 I/O 模型。

依赖项

下表将旧的 RESTEasy 依赖项与新的 Quarkus REST 依赖项进行了匹配。

旧版 Quarkus REST

quarkus-resteasy

quarkus-rest

quarkus-resteasy-jackson

quarkus-rest-jackson

quarkus-resteasy-jsonb

quarkus-rest-jsonb

quarkus-resteasy-jaxb

quarkus-rest-jaxb

quarkus-resteasy-qute

quarkus-rest-qute

quarkus-resteasy-mutiny 没有对应的依赖项,因为 Quarkus REST 开箱即用地提供了 Mutiny 集成。

注解

Quarkus REST 不支持 org.jboss.resteasy.annotations 包下的各种自定义注解。

下表将旧的 RESTEasy 注解与新的 Quarkus REST 注解进行了匹配。

旧版 Quarkus REST 注释

org.jboss.resteasy.annotations.jaxrs.PathParam

org.jboss.resteasy.reactive.RestPath

当路径部分与方法参数名匹配时,不需要此注解

org.jboss.resteasy.annotations.jaxrs.QueryParam

org.jboss.resteasy.reactive.RestQuery

org.jboss.resteasy.annotations.jaxrs.FormParam

org.jboss.resteasy.reactive.RestForm

org.jboss.resteasy.annotations.jaxrs.HeaderParam

org.jboss.resteasy.reactive.RestHeader

org.jboss.resteasy.annotations.jaxrs.CookieParam

org.jboss.resteasy.reactive.RestCookie

org.jboss.resteasy.annotations.jaxrs.MatrixParam

org.jboss.resteasy.reactive.RestMatrix

org.jboss.resteasy.annotations.cache.Cache

org.jboss.resteasy.reactive.Cache

org.jboss.resteasy.annotations.cache.NoCache

org.jboss.resteasy.reactive.NoCache

org.jboss.resteasy.annotations.SseElementType

org.jboss.resteasy.reactive.RestStreamElementType

org.jboss.resteasy.annotations.Separator

org.jboss.resteasy.reactive.Separator

上表不包含 org.jboss.resteasy.annotations.Form 注解,因为 Quarkus REST 没有专门的替代品。鼓励用户改用 Jakarta REST 标准的 jakarta.ws.rs.BeanParam 注解,该注解在服务器和客户端上都受支持。

Jakarta REST 提供者

尽管 Quarkus REST 提供了与 RESTEasy Classic 相同的符合规范的行为,但在运行时它不包含完全相同的提供者实现。

提供者差异可能导致行为不同的最常见情况是包含的 jakarta.ws.rs.ext.ExceptionMapper 实现。要查看应用程序中包含的类,请在开发模式下启动应用程序并导航到 https://:8080/q/dev-ui/io.quarkus.quarkus-rest/exception-mappers

服务加载

RESTEasy Classic 支持使用 Java 的 Service Loader 在构建时确定提供者。为了确保所有提供者都在构建时确定,Quarkus REST 不支持此功能。相反,鼓励在应用程序依赖项中拥有提供者的用户使用 CDI 指南的 Bean Discovery 部分所述的一种方法来索引这些依赖项。

Multipart 支持

Quarkus REST 中的 HTTP Multipart 支持 **不** 重用与 RESTEasy Classic 相同的类型或注解,因此鼓励用户阅读参考文档的 这部分

迁移 multipart 资源到 Quarkus REST 的用户应该注意配置参数 quarkus.http.limits.max-form-attribute-size,因为它对每个 part 的大小设置了上限。任何 part 大小超过此配置值的请求都将导致 HTTP 状态码 413。

默认媒体类型

Quarkus 在确定 Jakarta REST 方法的媒体类型时使用智能默认值,以简化常见用例。quarkus-restquarkus-resteasy 之间的区别在于,当方法返回 String 时,使用 text/plain 作为默认媒体类型,而不是 text/html

注入 @SessionScoped bean

目前不支持 @SessionScoped bean。如果您确实需要此功能,则需要使用 RESTEasy Classic 而不是 RESTEasy Reactive。

Servlet

Quarkus REST **不支持** Servlet。如果您的项目依赖于 Servlet,则必须迁移它们。基于 Servlet 的 JAX-RS 实现必须支持使用 @Context 注解注入以下类型:ServletConfigServletContextHttpServletRequestHttpServletResponse。由于 Quarkus REST 不是基于 Servlet 的,因此这些注入将无法工作。

这并不总是显而易见的,特别是如果您依赖于提供接口的 quarkus-undertow 等扩展。例如,如果您编写以下代码,它可能会编译,但在调用时会引发异常:

@Path("/reactive")
public class ReactiveResource {

    @Context
    HttpServletRequest httpServletRequest;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String servletContextPath() {

        String contextPath = httpServletRequest.getContextPath();

        return "My context path is: " + contextPath;
    }
}

对于您的第三方库也是如此。如果它们碰巧依赖于 Servlet,则需要为它们找到迁移路径。

记录身份验证和授权失败

Quarkus REST 端点的安全检查在调用 CDI 拦截器之前执行。记录 Quarkus Security 身份验证异常的最安全方法是确保启用主动身份验证并使用 Vert.x HTTP 路由失败处理程序。有关更多信息,请参阅主动身份验证指南的 自定义身份验证异常响应 部分。

客户端

REST Client(quarkus-rest-client 及其依赖项)取代了基于 RESTEasy Classic 的旧版 quarkus-resteasy-client,并利用了 Quarkus 的构建时处理以及 Vert.x 提供的统一 I/O 模型。

依赖项

下表将基于 RESTEasy Classic 的旧版 REST Client 依赖项与新的 REST Client 依赖项进行了匹配。

旧版 Quarkus REST

quarkus-resteasy-client

quarkus-rest-client

quarkus-resteasy-client-jackson

quarkus-rest-client-jackson

quarkus-resteasy-client-jsonb

quarkus-rest-client-jsonb

quarkus-resteasy-client-jaxb

quarkus-rest-client-jaxb

quarkus-resteasy-client-mutiny

无替代品,原生支持 Mutiny

Keycloak 管理客户端

使用 quarkus-rest-client 时,用户可以使用 quarkus-keycloak-admin-rest-client 来管理目标 Keycloak 实例,方法是利用 REST Client。

但是,在使用 quarkus-resteasy-client 时,用户必须使用 quarkus-keycloak-admin-resteasy-client 来访问相同的功能并使用基于 RESTEasy Classic 的旧版 REST Client。

OIDC

使用 quarkus-rest-client 时,用户可以使用 quarkus-rest-client-oidc-filter 扩展从 OpenID Connect 和 OAuth 2.0 兼容的授权服务器获取和刷新访问令牌。

但是,在使用 quarkus-resteasy-client 时,用户必须使用 quarkus-resteasy-client-oidc-filter 来访问相同的功能。

同样,quarkus-rest-client-oidc-token-propagation 允许使用旧版 REST 的用户传播当前的 BearerAuthorization Code Flow 访问令牌。

但是,在使用 quarkus-resteasy-client 时,用户必须使用 quarkus-resteasy-client-oidc-token-propagation 来访问相同的功能。

自定义扩展

这是一个高级部分,只有已开发了依赖于 Jakarta REST 和/或 REST Client 功能的自定义扩展的用户才需要阅读。

依赖项

首先要考虑的是自定义扩展是否应该显式依赖于 Quarkus REST,或者选择支持两种 RESTEasy 风格并由用户决定。如果扩展是通用目的的扩展,那么选择后一种选项可能更有意义,而当自定义扩展被特定的用户/应用程序集使用时,前一种选项最容易采用。

选择支持两种扩展时,自定义扩展的部署模块通常会依赖于 SPI 模块 - quarkus-jaxrs-spi-deploymentquarkus-resteasy-common-spiquarkus-rest-spi-deployment,而运行时模块将对两种 RESTEasy 风格的运行时模块具有 optional 依赖。

可以在 此处此处 看到 Quarkus 在核心存储库中支持这两种 RESTEasy 风格的几个良好示例。

总的来说,通常不需要为支持两种风格而拥有两个不同版本的自定义扩展。只有当希望扩展的消费者(即 Quarkus 应用程序)不必自己选择 RESTEasy 版本时,这种选择才是绝对必要的。

资源和提供者发现

包含 Jakarta REST 资源、提供者或 REST Client 接口在其运行时模块中,并且依赖于 Jandex 索引进行发现(例如,因为它们有一个空的 META-INF/beans.xml 文件)的自定义扩展,无需执行任何额外的设置即可使 Quarkus REST 发现它们。

通过 Build Items 注册提供者

通过 Build Items 注册提供者的扩展在 RESTEasy Classic 中使用 io.quarkus.resteasy.common.spi.ResteasyJaxrsProviderBuildItem Build Item。但在 Quarkus REST 中,扩展需要使用特定的 Build Items,例如 io.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItemio.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItem

REST 客户端

作为 Quarkus 应用程序一部分运行的任何代码,如果使用了 RESTEasy Client,则可以安全地使用 REST Client,因为所有必要的设置已在应用程序的静态初始化阶段完成。

相关内容