JAX-RS 2.0 行为更改
JAX-RS 2.0 实现包含一些行为更改。这些更改可能会导致应用程序的行为不同或者在 JAX-RS 2.0 上失败(如果应用程序是从 JAX-RS 1.1 进行升级的)。
以下列表描述 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 2.0 中不再显示在 JAX-RS 1.1 中显示为第三方 API 的 jackson 包。如果要在应用程序中使用任何 org.codehaus.jackson API,您需要在应用程序中压缩 jackson 包。
- 如果您在 web.xml 文件中指定 Servlet 名称
javax.ws.rs.core.Application,那么应用程序对象中的
getClasses 方法(由 @Context 注入)不会返回资源类。
<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 2.0 中不支持在 JAX-RS 1.1 中显示为第三方 API 的任何 Wink API。下面是不完整列表:
- 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 Filter,因此不再受支持。
注: 检测应用程序中是否存在 Wink JAR 包。如果应用程序中存在任何 Wink 包,那么您必须执行下列步骤:- 确保定义了应用程序子类。
- getClasses 和 getSingletons 中的至少一种方法不得返回 Null。
- 有关可以在 JAX-RS 2.0 客户机中使用的受支持客户机属性的更多信息,请参阅配置 JAX-RS 2.0 客户机。
- 如果要在 JAX-RS 2.0 中使用安全套接字层 (SSL),请执行下列步骤:
- 在 WebSphere® Application Server(传统) 管理控制台中配置 SSL 属性。
有关更多信息,请参阅创建安全套接字层配置。
- 对 JAX-RS 应用程序启用安全性,并将应用程序配置为在调用 REST 资源时使用 SSL 通道进行传输。
在应用程序开发或部署时,编辑 web.xml 文件以添加有关需要对资源使用 SSL 的安全性约束。请参阅“保护 Web 容器中的 JAX-RS 应用程序”信息,以获取更多有关对应用程序启用 SSL 的详细信息。
安全性约束元素内的以下元素指定为应用程序强制实施 SSL:<user-data-constraint id="UserDataConstraint_1"> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint>
- 要在开发客户机应用程序时启用客户机 SSL,请在客户机应用程序代码中添加客户机属性。
将客户机属性键设置为 com.ibm.ws.jaxrs.client.ssl.config,将其值设置为 true。请参阅以下代码片段作为参考:
ClientBuilder cb = ClientBuilder.newBuilder(); cb.property("com.ibm.ws.jaxrs.client.ssl.config", "NodeDefaultSSLSettings");
提示: 属性值即为您设置的服务器 SSL 别名。有关更多信息,请转到应用程序服务器 -> server n(其中 n 是对应用程序服务器指定的编号。)-> Web 容器传输链 -> WCInboundDefaultSecure -> SSL 入站通道 (SSL_2),以便在 SSL 配置字段下检查属性值。 - 使用管理控制台将客户机应用程序部署到 WebSphere Application Server(传统)。
- 在 WebSphere Application Server(传统) 管理控制台中启动客户机应用程序。
要启动应用程序,请转到应用程序 -> 应用程序类型 -> WebSphere 企业应用程序 -> 启动。
- 在 WebSphere® Application Server(传统) 管理控制台中配置 SSL 属性。
注: 有关客户机 API 和服务器 API 中的异步处理的更多信息,请参阅 JSR 339:JAX-RS 2.0:Java API for RESTful Web Services(“规范”)中的第 8 章。