JAX-RS 2.0 行为更改
JAX-RS 2.0 实现包含一些行为更改。这些更改可能导致从 JAX-RS 1.1 升级的应用程序在 JAX-RS 2.0 上的行为方式不同或失效。
以下列表描述 JAX-RS 1.1 与 JAX-RS 2.0 之间的差别:
- 在 JAX-RS 1.1 和 Jersey 中,如果 EJB 或 CDI 类创建新实例并且此实例由 JAX-RS application.getSingletons()
方法返回,那么引擎使用所返回实例并且不会尝试从 EJB 或 CDI 容器访问该实例。在 JAX-RS 2.0
中,对于同一场景,引擎尝试从 EJB 或 CDI 容器访问该实例。如果可访问该实例,那么会使用检索到的实例。但是,如果无法访问该实例,那么会使用从 getSingletons()
方法返回的实例。例如:
@Override public SetObject getSingletons() { SetObject objs = new HashSetObject(); objs.add(new CDIInjectResource()); objs.add(new EJBInjectResource()); return objs; }
JAX-RS 2.0 处理多重部件文件时包含许多 API 更改。例如,在 JAX-RS 1.1 中,可使用 @FormParam 来处理多重部件文件,但在 JAX-RS 2.0 中,只能使用 @IMultipartBody 或 @IAttachment 来处理多重部件文件。有关更多信息,请参阅配置资源以通过 JAX-RS 2.0 中的 HTML 表单提交接收 multipart/form-data 部分。
- 在 JAX-RS 1.1 中显示为第三方 API 的 jackson 包不再显示在 JAX-RS 2.0 中。如果您要在应用程序中使用任何 org.codehaus.jackson API,您需要在应用程序中压缩 jackson 包。
- 如果在 web.xml 文件中指定 javax.ws.rs.core.Application 作为 servlet
名称,那么 @Context 在 Application 对象中注入的
getClasses 方法不会返回资源类。
<servlet> <servlet-name>javax.ws.rs.core.Application</servlet-name> </servlet> <servlet-mapping> <servlet-name>javax.ws.rs.core.Application</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
- JAX-RS 2.0 规范声明提供者是一个类,该类实现一个或多个 JAX-RS
接口并可使用 @Provider 进行注释以执行自动发现。在此场景中,某个类具有引用提供者接口的
@Local 注释,但它未实现任何 POJO 提供者接口,那么它是无效提供者。例如:
@Stateless @Local(OneLocalInterfaceMyOtherStuffMessageBodyWriter.class) public class OneLocalInterfaceMyOtherStuffProvide
- 如果使用 MessageBodyReader 和 MessageBodyWriter @Consumes 及 @Produces 注释,那么一些受支持介质类型可能受到限制。请使用 isReadable 方法或
isWriteable 方法来检查介质类型。例如:
@Provider @Consumes("<custom/type>") @Produces("<custom/type>") @Singleton public class MyMessageBodyReaderAndWriter implements MessageBodyReader,MessageBodyWriter { public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { if (mediaType.toString().equals("<custom/type>")) return true; return false; } public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { if (mediaType.toString().equals("<custom/type>")) return true; return false; } ... }
- 可在 JAX-RS 2.0 中使用异步处理来处理线程。有关更多信息,请参阅异步处理。
- 在 JAX-RS 1.1 中显示为第三方 API 的 Wink API 在 JAX-RS 2.0 中都不受支持。以下是部分列表:
- org.apache.wink.common.model.atom.AtomEntry。有关将 JAX-RS 2.0 与 Atom 集成的更多信息,请参阅JAX-RS 2.0 与 Atom 的集成。
- org.apache.wink.client.handlers.BasicAuthSecurityHandler。如果要在 JAX-RS 2.0 中使用基本认证,请查看以下代码片段:
- 如代码示例中所示,通过 JAX-RS 2.0 标准客户机 API 使用 ClientRequestFilter:
import java.io.IOException; import java.io.UnsupportedEncodingException; import javax.ws.rs.client.ClientRequestContext; import javax.ws.rs.client.ClientRequestFilter; import javax.ws.rs.core.MultivaluedMap; import javax.xml.bind.DatatypeConverter; public class BasicAuthFilter implements ClientRequestFilter { private final String usr; private final String pwd; public BasicAuthFilter(String usr, String pwd) { this.usr = user; this.pwd = pwd; } public void filter(ClientRequestContext requestContext) throws IOException { MultivaluedMap<String, Object> headers = requestContext.getHeaders(); String token = this.usr + ":" + this.pwd; final String basicAuthentication ="Basic " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8")); headers.add("Authorization", basicAuthentication); } }
- 注册至 ClientBuilder:
ClientBuilder cb = ClientBuilder.newBuilder(); cb.register(new BasicAuthFilter("user","password"));
- 如代码示例中所示,通过 JAX-RS 2.0 标准客户机 API 使用 ClientRequestFilter:
- org.apache.wink.client.handlers.LtpaAuthSecurityHandler。如果要使用基于 LTPA 的安全客户机保护下游资源,请参阅保护下游 JAX-RS 资源。
- org.apache.wink.server.internal.providers.exception.EJBAccessExceptionMapper。此 API 不再受支持,因为它是 Wink 指定的 ExceptionMapper。可定义您自己的 ExceptionMapper 以映射 EJBAccessException。
- com.ibm.websphere.jaxrs.server.IBMRestFilter。此 API 不再受支持,因为它基于 Wink 过滤器。
注:检测应用程序中是否有 Wink JAR 包。如果应用程序中有任何 Wink 包,那么必须执行以下步骤:
- 确保已定义应用程序子类。
- getClasses 和 getSingletons 的至少其中之一不得返回空值。
- 有关可在 JAX-RS 2.0 客户机中使用的受支持客户机属性的更多信息,请参阅配置 JAX-RS 2.0 客户机。
- 如果要在 JAX-RS 2.0 中使用安全套接字层 (SSL) 功能,请执行以下步骤:
- 启用 ssl-1.0 功能部件或 appSecurity-2.0 功能部件。对于 LTPA 令牌功能,appSecurity-2.0 功能部件是必需的。注: ssl-1.0 功能部件是 appSecurity-2.0 功能部件的子代。如果启用 jaxrsClient-2.0 功能部件和 ssl-1.0 功能部件,那么将自动启用 appSecurity-2.0 功能部件。
- 按如下所示在 JAX-RS 2.0 客户机代码中启用 com.ibm.ws.jaxrs.client.ssl.config 属性:
ClientBuilder cb = ClientBuilder.newBuilder(); Client c = cb.build(); c.property("com.ibm.ws.jaxrs.client.ssl.config", "mySSLConfig"); //mySSLConfig is the ssl ref id in Liberty server.xml
注: 此属性可将 Liberty SSL 配置绑定至 ClientBuilder、客户机和 WebTarget 作用域。
- 启用 ssl-1.0 功能部件或 appSecurity-2.0 功能部件。对于 LTPA 令牌功能,appSecurity-2.0 功能部件是必需的。
- 如果要在 JAX-RS 2.0 服务器运行时中使用 Wink 客户机,请执行以下步骤:
- 下载以下文件,它们可在 JAX-RS 2.0 服务器运行时中启用 Wink 客户机。
- 从 http://wink.apache.org/downloads.html 下载 Apache Wink 及相关 JAR 文件。
- 从 http://hc.apache.org/ 下载 Apache HTTP 及相关 JAR 文件。
注: 如果未启用该 JAX-RS 2.0 功能部件,那么还必须下载 JAX-RS API 并将其添加至第三方库。从 https://jax-rs-spec.java.net/nonav/ 下载 JAX-RS API。 - 将所有 JAR 文件保存到 <third-party lib> 目录中。
- 将 <third-party lib> 的位置添加至 server.xml 文件:
<library id="thirdPartyLib"> <fileset dir=" <third-party lib>" includes="*.jar" scanInterval="5s"/> </library> <enterpriseApplication id="<Your Ear ID>" location="<Your Ear Name>" name="<Your Ear Name>"> <classloader commonLibraryRef="thirdPartyLib"/> </enterpriseApplication>
- 下载以下文件,它们可在 JAX-RS 2.0 服务器运行时中启用 Wink 客户机。
注: 有关在客户机和服务器 API 中进行异步处理的更多信息,请参阅
JSR 339:
JAX-RS 2.0: The Java API for RESTful Web Services(“规范”)的第 8 章。