JAX-RS 2.0 行為變更
從第 9 版開始,Liberty 支援 JAX-RS 2.0。在 Liberty 中開始使用 JAX-RS 之前,您可能需要知道 JAX-RS 1.1 與 JAX-RS 2.0 之間的下列差異。
下列項目是 Liberty 中 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 Set<Object> getSingletons() { Set<Object> objs = new HashSet<Object>(); 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 組件。
下列項目適用於 Liberty 中的 JAX-RS 2.0:
- 在 JAX-RS 1.1 中顯示成協力廠商 API 的 Jackson 套件,不再顯露於 JAX-RS 2.0 中。如果您想在應用程式中使用任何 org.codehaus.jackson API,必須在您的應用程式中壓縮
Jackson 套件。如果要使用 JAX-RS 2.0 來處理 Java 物件中的 Jackson 註釋,您必須置換您應用程式類別中的
getSingletons(),以傳回 Jackson 的 JSON 提供者。
@Override public Set<Object> getSingletons() { Set<Object> singletons = new HashSet<Object>(); singletons.add(new JacksonJaxbJsonProvider()); return singletons; }
- 如果您在 web.xml 檔中,指定 javax.ws.rs.core.Application 作為 Servlet 名稱,應用程式物件中 @Context 所注入的 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 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 中使用基本鑑別 (BA),請參閱下列程式碼 Snippet:
- 透過 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 2.0 中將資源配置成接收 HTML 表單提交中的 multipart/form-data 組件。
- 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 不得傳回空值。
- 如果您想查看可在 JAX-RS 2.0 用戶端中使用的支援用戶端內容,請參閱配置 JAX-RS 2.0 用戶端。
- 如果您想在 JAX-RS 2.0 中使用 Secure Sockets Layer (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 伺服器執行時期中使用 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,並新增至 third-party lib。從 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 用戶端。
註: 如需 Client API 和 Server API 中非同步處理的相關資訊,請參閱 JSR 339:
JAX-RS 2.0: The Java API for RESTful Web Services 的第 8 章 "Specification"。