デコレーターおよびメソッド・インターセプターを使用した JAX-RS リソースの実装
Java™ Contexts and Dependency Injection (JCDI) を使用して、Java API for RESTful Web Services (JAX-RS) リソース・タイプのインターセプターおよびデコレーターを作成することができます。例えば、 JAX-RS を使用する JCDI 対応の Web アプリケーションを使用する場合に、 JCDI のインターセプター機能およびデコレーター機能を使用して、特定のクラスの呼び出しをログに記録したり、 メソッドを呼び出す前にセキュリティー検査を実行したりすることができます。
このタスクについて
横断的関心事 (cross-cutting concern) をアプリケーションに追加するための方法は 2 つあります。インターセプター・バインディングにはカスタム・アノテーションが必要です。アノテーションを使用して、 インターセプトするメソッドをマークします。デコレーターは基本タイプを実装します。 さらに、@javax.decorator.Decorator 注入インスタンスを使用して、 呼び出しの前後の特殊なロジックを注入委任オブジェクトに実装することができます。
手順
- メソッドがインターセプトされることを示すアノテーションを作成します。 この SecurityChecked アノテーションは、なんらかのセキュリティー情報を
検査するメソッドを示します。以下の例には、カスタム・アノテーションとインターセプトされるメソッド
が示されています。
package com.example.jaxrs; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.interceptor.InterceptorBinding; @Inherited @InterceptorBinding @Target( {ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface SecurityChecked { }
- JAX-RS リソース・クラスを作成し、インターセプトするメソッドに
@com.example.jaxrs.SecurityChecked アノテーションを付けます。 以下の例には、JAX-RS リソース・クラスとインターセプトされるメソッドが示されています。
package com.example.jaxrs; import javax.enterprise.context.RequestScoped; import javax.ws.rs.Path; import javax.ws.rs.GET; @Path("exampleInterceptor") @RequestScoped public class MyResourceBean { @GET @com.example.jaxrs.SecurityChecked public String echo(String hello) { return "Hello world!"; } }
- @javax.interceptor.Interceptor アノテーションおよび @com.example.jaxrs.SecurityChecked インターセプター・マーカーによって
アノテーションが付けられたインターセプター・クラスを作成します。作成後、javax.interceptor.InvocationContext パラメーターを指定した @javax.interceptor.AroundInvoke アノテーション付きメソッドを追加します。 InvocationContext メソッドを使用して、
メソッド呼び出しを検査し、呼び出しを処理するべきかどうかも判断します。
以下の例は、インターセプターを示しています。
package com.example.jaxrs; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; @Interceptor @com.example.jaxrs.SecurityChecked public class SecurityCheckInterceptor { @AroundInvoke public Object checkSecurity(InvocationContext context) throws Exception { /* check the parameters or do a generic security check before invoking the original method */ Object[] params = context.getParameters(); /* if security validation fails, you can throw an exception */ /* invoke the proceed() method to call the original method */ Object ret = context.proceed(); /* perform any post method call work */ return ret; } }
- WEB-INF ディレクトリー内の Web アプリケーション (WAR) に beans.xml デプロイメント記述子を追加します。 WEB-INF/beans.xml ファイルがあるということは、
アーカイブが JCDI 対応のアーカイブであることを示しています。このインスタンスの情報を
追加する必要があります。以下の例は、インターセプターがリストされた WEB-INF/beans.xml ファイルを示しています。
前のステップで、JCDI を使用するように Web アプリケーションを構成して、 インターセプトするメソッドをマークするためのカスタム・アノテーションを追加し、 インターセプターを作成しました。マークが付いたメソッドが呼び出されると、 インターセプターが使用され、マークされたメソッドを呼び出すかどうかを判別し、 追加ロジックを実行します。インターセプターは、 beans.xml デプロイメント記述子にリストする必要があります。<?xml version="1.0 encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http:// java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>com.example.jaxrs.SecurityCheckInterceptor</class> </interceptors> </beans>
これ以降のステップで、JCDI 対応 Web アプリケーションにデコレーターを作成して使用可能にします。 インターセプター・バインディングでは、インターセプトするメソッドをマークするためのアノテーションが必要です。デコレーターは、共通基本タイプを実装し、呼び出しをラップすることができます。
- デコレーターが実装しなければならない基本タイプを検索または作成します。 例えば、基本タイプが Item というインターフェースであるとします。
以下の例は、デコレーターによって使用される共通インターフェースを示しています。
package com.example.jaxrs; import javax.ws.rs.GET; public interface Item { @GET public String getInformation(); }
- 基本タイプを実装する標準 JAX-RS リソース・クラスを作成します。 以下の例は、装飾される JAX-RS リソース・クラスを示しています。
package com.example.jaxrs; import javax.enterprise.context.RequestScoped; import javax.ws.rs.Path; @Path("decoratedresource") @RequestScoped public class MyItem implements Item { public String getInformation() { /* return some information */ } }
- デコレーター・クラスを作成します。 デコレーター・クラスは、すべての呼び出しをラップする基本タイプを実装する必要があります。
デコレーターには、@javax.decorator.Decorator アノテーションを付けなければなりません。
デコレーターでは、基本タイプのほかに委任注入ポイントと呼ばれる特殊なフィールドが必要になります。 このフィールドは、任意の変数名を持つことができ、 @javax.inject.Inject アノテーションと @javax.decorator.Delegate アノテーションがなければなりません。このフィールドは、装飾されるオブジェクトのオリジナル・オブジェクトになります。この装飾されたオブジェクトを実装の呼び出しで使用することができます。
以下の例は、基本的なデコレーター・クラスを示しています。
package com.example.jaxrs; import javax.decorator.Decorator; import javax.decorator.Delegate; import javax.inject.Inject; @Decorator public class MyItemDecorator implements Item { @Inject @Delegate private Item decoratedItem; public String getInformation() { /* perform some logging */ String info = decoratedItem.getInformation(); /* perform some more logging */ return info; } }
- WEB-INF ディレクトリー内の Web アプリケーション (WAR) ファイルに beans.xml デプロイメント記述子を追加します。 WEB-INF/beans.xml ファイルがあるということは、
アーカイブが JCDI 対応のアーカイブであることを示しています。このインスタンスのアクティブな
デコレーター・クラスに関する情報を追加する必要があります。以下の例は、デコレーターがリストされた WEB-INF/beans.xml ファイルを示しています。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http:// java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>com.example.jaxrs.SecurityCheckInterceptor</class> </interceptors> <decorators> <class>com.example.jaxrs.MyItemDecorator</class> </decorators> </beans>
タスクの結果
JCDI を使用するように Web アプリケーションを構成し、 1 つのリソースのメソッド・インターセプターを作成しました。また、デコレーターを作成し、 そのデコレーターが 2 番目のリソースに対するメソッド呼び出しを装飾するようにしました。


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_jaxrs_jcdi_decoratorsandmethod
ファイル名:twbs_jaxrs_jcdi_decoratorsandmethod.html