7.4. Jakarta RESTful Web 服务和 RESTEasy 应用更改
JBoss EAP 6 捆绑了 RESTEasy 2,它是 JAX-RS 1.x 的实施。
JBoss EAP 8 和 JBoss EAP 7.1 包括 RESTEasy 3.0.x,它是 JSR 339: JAX-RS 2.0 定义的 JAX-RS 2.0:用于 RESTful Web 服务的 Java API。
JBoss EAP 8.0 包括 RESTEasy 3.15,这是 Jakarta RESTful Web Services 2.1 的实施。此发行版本还添加了对 JDK 11 的支持。在提供一些 RESTEasy 4 主要功能时,这个版本基于 RESTEasy 3.0,确保完全向后兼容。因此,您应该在从 RESTEasy 3.0 迁移到 RESTEasy 3.15 时遇到一些问题。有关 RESTEasy RESTEasy 3.15 的 Java API 的更多信息,请参阅 RESTEasy Jakarta RESTful Web Services 3.15.0.Final API。
JBoss EAP 8.1 支持 RESTEasy 6.2,其实施 Jakarta RESTful Web 服务 3.1 规范。
如果您要从 JBoss EAP 6.4 迁移,请注意 JBoss EAP 中包含的 Jackson 版本发生了变化。JBoss EAP 6.4 包括 Jackson 1.9.9。JBoss EAP 7 及更高版本现在包含 Jackson 2.6.3 或更高版本。
本节介绍这些更改如何影响使用 RESTEasy 或 Jakarta RESTful Web 服务的应用程序。
7.4.1. RESTEasy 弃用的类 复制链接链接已复制到粘贴板!
- 拦截器和 MessageBody 类
-
JSR 311:JAX-RS:RESTful Web 服务的 Java™ API 没有包含拦截器框架,因此 RESTEasy 2 提供一个。JSR 339: JAX-RS 2.0:RESTful Web 服务的 Java API 引入了官方拦截器和过滤框架,因此 RESTEasy 2 中包含的拦截器框架现已弃用,并被 RESTEasy 3.x 中的 Jakarta REST 兼容拦截器功能替代。相关的接口在
jakarta.ws.rs.api模块的jakarta.ws.rs.ext软件包中定义。
JBoss EAP 8.0 中删除了以下提供程序:
-
org.jboss.resteasy:resteasy-jackson-provider -
org.jboss.resteasy:resteasy-jettison-provider -
org.jboss.resteasy:resteasy-yaml-provider
JBoss EAP 8.0 中删除了以下内容,因为它们现在有 Jakarta RESTful Web 服务替换。
-
@suspend和org.jboss.resteasy.spi.AsynchronousResponse已被删除,并分别替换为@Suspended和javax.ws.rs.container.AsyncResponse。 -
StringConverter被ParamConverter替换。 -
org.jboss.resteasy.plugins.providers.SerializableProvider已被弃用,并已被删除。 RESTEasy 3.x 中已弃用的以下拦截器接口已被删除。
-
org.jboss.resteasy.spi.interception.PreProcessInterceptor接口被 RESTEasy 3.x 中的jakarta.ws.rs.container.ContainerRequestFilter接口替代。 以下接口和类已从 RESTEasy 3.x 和 JBoss EAP 8.0 中删除。
-
org.jboss.resteasy.spi.interception.MessageBodyReaderInterceptor -
org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor -
org.jboss.resteasy.spi.interception.MessageBodyWriterContext -
org.jboss.resteasy.spi.interception.MessageBodyReaderContext -
org.jboss.resteasy.core.interception.InterceptorRegistry -
org.jboss.resteasy.core.interception.InterceptorRegistryListener -
org.jboss.resteasy.core.interception.ClientExecutionContextImpl
-
-
org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor接口被jakarta.ws.rs.ext.WriterInterceptor接口替代。 另外,
jakarta.ws.rs.ext.MessageBodyWriter接口的一些更改可能不向后兼容 JAX-RS 1.x。如果您的应用使用了 JAX-RS 1.x,请检查您的应用程序代码,以确保为您的端点定义了@Produces或@Consumes。如果不这样做,可能会导致错误类似如下。org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: <OBJECT> of media type:以下是可能导致此错误的 REST 端点示例。
@Path("dates") public class DateService { @GET @Path("daysuntil/{targetdate}") public long showDaysUntil(@PathParam("targetdate") String targetDate) { DateLogger.LOGGER.logDaysUntilRequest(targetDate); final long days; try { final LocalDate date = LocalDate.parse(targetDate, DateTimeFormatter.ISO_DATE); days = ChronoUnit.DAYS.between(LocalDate.now(), date); } catch (DateTimeParseException ex) { // ** DISCLAIMER **. This example is contrived. throw new WebApplicationException(Response.status(400).entity(ex.getLocalizedMessage()).type(MediaType.TEXT_PLAIN) .build()); } return days; } }要解决这个问题,请添加
jakarta.ws.rs.Produces和@Produces注解的导入,如下所示:... import jakarta.ws.rs.Produces; ... @Path("dates") public class DateService { @GET @Path("daysuntil/{targetdate}") @Produces(MediaType.TEXT_PLAIN) public long showDaysUntil(@PathParam("targetdate") String targetDate) { DateLogger.LOGGER.logDaysUntilRequest(targetDate); final long days; try { final LocalDate date = LocalDate.parse(targetDate, DateTimeFormatter.ISO_DATE); days = ChronoUnit.DAYS.between(LocalDate.now(), date); } catch (DateTimeParseException ex) { // ** DISCLAIMER **. This example is contrived. throw new WebApplicationException(Response.status(400).entity(ex.getLocalizedMessage()).type(MediaType.TEXT_PLAIN) .build()); } return days; } }
来自以前版本的 RESTEasy 的所有拦截器都可以与新的 Jakarta REST 过滤器和拦截器接口并行运行。
7.4.1.1. 客户端 API 复制链接链接已复制到粘贴板!
resteasy-jaxrs 中的 RESTEasy 客户端框架被 JBoss EAP 7.0 中的遵循 JAX-RS 2.0 的 resteasy-client 模块替代。因此,一些 RESTEasy 客户端 API 类和方法已弃用。
以下类已从 JBoss EAP 8.0 中删除:
-
org.jboss.resteasy.client.ClientResponseFailure异常和org.jboss.resteasy.client.ClientExecutor和org.jboss.resteasy.client.EntityTypeFactory接口也被弃用。 您必须将
org.jboss.resteasy.client.ClientRequest和org.jboss.resteasy.client.ClientResponse类分别替换为org.jboss.resteasy.client.jaxrs.ResteasyClient和jakarta.ws.rs.core.Response。以下是如何在 RESTEasy 2.3.x 中使用 RESTEasy 客户端发送链接标头的示例。
ClientRequest request = new ClientRequest(generateURL("/linkheader/str")); request.addLink("previous chapter", "previous", "http://example.com/TheBook/chapter2", null); ClientResponse response = request.post(); LinkHeader header = response.getLinkHeader();以下是如何通过 RESTEasy 3 中的 RESTEasy 客户端完成相同的任务。
ResteasyClient client = new ResteasyClientBuilder().build(); Response response = client.target(generateURL("/linkheader/str")).request() .header("Link", "<http://example.com/TheBook/chapter2>; rel=\"previous\"; title=\"previous chapter\"").post(Entity.text(new String())); jakarta.ws.rs.core.Link link = response.getLink("previous");如需与 Jakarta REST Web 服务交互的外部 Jakarta REST RESTEasy 客户端的示例,请参阅
resteasy-jaxrs-clientQuickstart。-
org.jboss.resteasy.client.cache软件包中的类和接口也被弃用。它们由org.jboss.resteasy.annotations.cache软件包中的等效类和接口替代。
有关 org.jboss.resteasy.client.jaxrs API 类的更多信息,请参阅 RESTEasy Jakarta REST JavaDoc。
- StringConverter
-
org.jboss.resteasy.spi.StringConverter类在 RESTEasy 3.x 和 JBoss EAP 8.0 中弃用。此功能可以使用 Jakarta REST jakarta.ws.rs.ext.ParamConverterProvider 类来替换。
7.4.2. 删除或保护的 RESTEasy 类 复制链接链接已复制到粘贴板!
- ResteasyProviderFactory 添加方法
-
大多数
org.jboss.resteasy.spi.ResteasyProviderFactoryadd ()方法已被删除或在 RESTEasy 3.0 中受到保护。例如,addBuiltInMessageBodyReader()和addBuiltInMessageBodyWriter()方法已被删除,并且addMessageBodyReader()和addMessageBodyWriter()方法受保护。
现在,您应该使用 registerProvider () 和 registerProviderInstance () 方法。
- 从 RESTEasy 3 中删除额外的类
-
@org.jboss.resteasy.annotations.cache.ServerCached注释指定对 Jakarta REST 方法的响应应缓存在服务器上,它已从 RESTEasy 3 中删除,且必须从应用程序代码中删除。
7.4.3. 其他 RESTEasy 更改 复制链接链接已复制到粘贴板!
本节提供有关 JBoss EAP 的 RESTEasy 中一些其他更改的信息。
- SignedInput 和 SignedOuput
-
resteasy-crypto的SignedInput和SignedOutput必须在Request或Response对象中将Content-Type设置为multipart/signed,或使用@Consumes或@Produces注解。 -
您可以通过在
@Produces或@Consumes注解中设置类型,使用SignedOutput和SignedInput以二进制形式返回application/pkcs7-signatureMIME 类型格式。 -
如果
@Produces或@Consumes是text/plainMIME 类型,则SignedOutput将采用 base64 编码并作为 String 发送。
-
- 安全过滤器
-
@RolesAllowed、@PermitAll和@DenyAll的安全过滤器现在返回 "403 Forbidden" 而不是 "401 Unauthorized"。 - 客户端过滤器
- 从 RESTEasy 3.0 之前,从版本使用 RESTEasy 客户端 API 时,在 JAX-RS 2.0 中引入的客户端侧过滤器不会绑定并运行。
- 异步 HTTP 支持
-
由于 JAX-RS 2.0 规范增加了使用
@Suspended注释和AsynResponse接口的异步 HTTP 支持,因此用于异步 HTTP 的 RESTEasy 专有 API 已被弃用,并可能在以后的 RESTEasy 发行版本中删除。异步 Tomcat 和异步 JBoss Web 模块也已从服务器安装中删除。如果您不使用 Servlet 3.0 容器或更高,则异步 HTTP 服务器端处理将模拟,并在同一个请求线程中异步运行。 - 服务器端缓存
- 服务器端缓存设置已更改。如需更多信息,请参阅 RESTEasy 文档。
- YAML 提供程序设置更改
-
在以前的 JBoss EAP 版本中,RESTEasy YAML 供应商设置被默认启用。这在 JBoss EAP 7 中有所改变。现在默认禁用 YAML 供应商。由于 RESTEasy 用于 unmarshalling 的
SnakeYAML库中的安全问题,它不被支持,因此必须在应用中明确启用。有关如何在应用程序中启用 YAML 供应商并添加 Maven 依赖项的信息,请参阅 JBoss EAP 8.0 开发 Web Services Applications 中的 YAML 提供程序。
- Content-Type Header 中的默认 Charset UTF-8
-
自 JBoss EAP 7.1 起,
resteasy.add.charset参数默认设置为true。当资源方法返回一个text/*或application/xml*媒介类型且没有明确的字符集时,如果您不希望 RESTEasy 将charset=UTF-8添加到返回的 content-type 头时,可以将resteasy.add.charset参数设置为false。
如需有关文本媒体类型和字符集的更多信息,请参阅 JBoss EAP 7.4 开发 Web 服务应用 中的文本媒体类型和 字符集。
- SerializableProvider
-
从不受信任的源中反序列化 Java 对象是不安全的。因此,从 JBoss EAP 7 开始,默认禁用
org.jboss.resteasy.plugins.providers.SerializableProvider类,我们不推荐使用这个提供程序。
- 将请求与资源方法匹配
- 在 RESTEasy 3 中,对匹配规则实施进行了改进和纠正,如 JAX-RS 规范中定义的。特别是,对处理子资源方法和子资源 locator 上的模糊 URI 进行了更改。
在 RESTEasy 2 中,即使存在具有相同 URI 的另一个子资源,子资源 locator 也可以成功执行。这个行为根据规格不正确。
在 RESTEasy 3 中,当子资源和子资源 locator 中有模糊的 URI 时,调用子资源将成功;但调用子资源 locator 将导致 HTTP 状态 405 方法 Not Allowed 错误。
以下示例包含子资源方法和子资源 locator 上的模糊 @Path 注释。注意端点 anotherResource 和 anotherResourceLocator 的 URI 相同。这两个端点之间的区别在于 anotherResource 方法与 REST 动词 POST 关联。anotherResourceLocator 方法不与任何 REST 动词关联。根据规范,将始终选择具有 REST 动词的端点(本例中为 anotherResource 方法)。
@Path("myResource")
public class ExampleSubResources {
@POST
@Path("items")
@Produces("text/plain")
public Response anotherResource(String text) {
return Response.ok("ok").build();
}
@Path("items")
@Produces("text/plain")
public SubResource anotherResourceLocator() {
return new SubResource();
}
}
7.4.4. RESTEasy SPI 更改 复制链接链接已复制到粘贴板!
JBoss EAP 8 中删除了 RESTEasy SPI 提供程序。
- SPI Exceptions
- 所有 SPI 失败例外已被弃用,不再在内部使用。它们已被对应的 Jakarta REST 例外替代。
| 弃用的例外 | 替换 jaxrs-api 模块中的例外 |
|---|---|
| org.jboss.resteasy.spi.ForbiddenException | jakarta.ws.rs.ForbiddenException |
| org.jboss.resteasy.spi.MethodNotAllowedException | jakarta.ws.rs.NotAllowedException |
| org.jboss.resteasy.spi.NotAcceptableException | jakarta.ws.rs.NotAcceptableException |
| org.jboss.resteasy.spi.NotFoundException | jakarta.ws.rs.NotFoundException |
| org.jboss.resteasy.spi.UnauthorizedException | jakarta.ws.rs.NotAuthorizedException |
| org.jboss.resteasy.spi.UnsupportedMediaTypeException | jakarta.ws.rs.NotSupportedException |
- InjectoronnectionFactoryy 和 Registry
-
InjectorFactory和RegistrySPI 已更改。如果使用 RESTEasy 作为文档和支持,这不应有问题。
7.4.5. Jackson 供应商更改 复制链接链接已复制到粘贴板!
JBoss EAP 6.4 中包含的 Jackson 版本已更改。从 JBoss EAP 7 开始,Jackson 供应商已从 resteasy-jackson-provider 改为 resteasy-jackson2-provider。
升级到 resteasy-jackson2-provider 需要一些软件包更改。例如,Jackson 注解软件包已从 org.codehaus.jackson.annotate 改为 com.fasterxml.jackson.annotation。
7.4.6. Spring RESTEasy 集成更改 复制链接链接已复制到粘贴板!
JBoss EAP 8.1 支持 RESTEasy 6.2。如果您计划将 Spring 6.0 框架与 JBoss EAP 8.1 搭配使用,则必须使用 Java 17。
Spring 4.0 框架引入了对 Java 8 的支持。如果您计划将 RESTEasy 3.x 与 Spring 集成,请确保将 4.2.x 指定为部署中的最小 Spring 版本,因为这是 JBoss EAP 7 支持的最早稳定版本。
7.4.7. RESTEasy Jettison JSON 供应商更改 复制链接链接已复制到粘贴板!
自 JBoss EAP 7 起,Easy Jettison JSON 提供程序已被弃用,默认情况下不再添加到部署中。建议您切换到推荐的 RESTEasy Jackson 供应商。如果您希望继续使用 Jettison 供应商,您必须在 jboss-deployment-descriptor.xml 文件中定义一个明确的依赖关系,如下例所示。
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.jboss.resteasy.resteasy-jackson2-provider"/>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
</exclusions>
<dependencies>
<module name="org.jboss.resteasy.resteasy-jettison-provider" services="import"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
有关如何定义显式依赖项的更多信息,请参阅 JBoss EAP 7.4 开发指南中的 向部署添加明确模块依赖。
7.4.8. MicroProfile for JBoss EAP 复制链接链接已复制到粘贴板!
MicroProfile 是规范的名称,开发人员可以用于配置应用和微服务在多个环境中运行,而无需修改或重新打包这些应用程序。在以前的版本中,MicroProfile 作为技术预览提供 JBoss EAP 7.3,但自此后已被删除。MicroProfile 现在仅适用于 JBoss EAP XP。