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 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 パーツを受信するためのリソースの構成』を参照してください。
Liberty では、以下の項目が JAX-RS 2.0 に適用されます。
- JAX-RS 1.1 でのサード・パーティー API としての jackson パッケージが、JAX-RS 2.0 では表示されなくなりました。 ご使用のアプリケーションでいずれかの org.codehaus.jackson API を使用する場合は、jackson パッケージを圧縮してアプリケーションに含める必要があります。
- web.xml ファイルで servlet-name として javax.ws.rs.core.Application を指定した場合、@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 仕様の規定では、プロバイダーとは、自動ディスカバリーのために @Provider のアノテーションが付けられる可能性があるクラスであり、かつ 1 つ以上の JAX-RS インターフェースを実装したクラスです。シナリオでは、クラスにプロバイダー・インターフェースを参照する @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 2.0 で HTML フォームの実行依頼から multipart/form-data パーツを受信するためのリソースの構成を参照してください。
- org.apache.wink.server.internal.providers.exception.EJBAccessExceptionMapper。 この API は、Wink 指定の ExceptionMapper であるため、サポートされなくなりました。EJBAccessException をマップする独自の ExceptionMapper を定義できます。
- com.ibm.websphere.jaxrs.server.IBMRestFilter。この API は、Wink フィルターに基づいているため、サポートされなくなりました。
注: アプリケーション内に wink jar パッケージがあるかどうか調べてください。 アプリケーションに wink パッケージが存在する場合、以下のステップを実行する必要があります。- Application サブクラスが定義されていることを確認します。
- getClasses と getSingletons の少なくとも 1 つがヌルを返してはなりません。
- 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 をダウンロードしてサード・パーティー・ライブラリーに追加する必要もあります。https://jax-rs-spec.java.net/nonav/ から JAX-RS API をダウンロードします。 - <third-party lib> ディレクトリーにすべての JAR ファイルを保存します。
- server.xml ファイルに <third-party lib> のロケーションを追加します。
<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 およびサーバー API での非同期処理について詳しくは、「JSR 339: JAX-RS 2.0: The Java API for RESTful Web Services」(「仕様」) の第 8 章を参照してください。