47.3. パラメーターコンバーター
概要
パラメーターコンバーターを使用すると、パラメーター (String
型の) をフィールド、Bean プロパティー、またはリソースメソッド引数の 任意 の型に注入することができます。適切なパラメーターコンバーターを実装してバインディングすることで、JAX-RS ランタイムを拡張して、パラメーター文字列の値をターゲットタイプに変換できます。
自動変換
パラメーターは String
のインスタンスとして受信されるため、String
型のフィールド、Bean プロパティー、およびメソッドパラメーターに常に注入することができます。さらに、JAX-RS ランタイムには、パラメーター文字列を以下の型に自動的に変換する機能があります。
- プリミティブ型。
-
単一の
String
引数を受け入れるコンストラクターを持つ型。 -
型のインスタンスを返す String 引数が 1 つあり、
valueOf
またはfromString
という名前の静的メソッドを持つ型。 -
T
が 2 または 3 で説明する型のいずれかの場合、List<T>
、Set<T>
、またはSortedSet<T>
。
パラメーターコンバーター
自動変換が対応していない型にパラメーターを注入するには、型のカスタム パラメーターコンバーター を定義できます。パラメーターコンバーターは、String
からカスタムタイプへの変換、およびカスタムタイプから String
への逆方向の変換を定義できる JAX-RS エクステンションです。
ファクトリーパターン
JAX-RS パラメーターコンバーターメカニズムは、ファクトリーパターンを使用します。したがって、パラメーターコンバーターを直接登録するのではなく、パラメーターコンバータープロバイダー (型 javax.ws.rs.ext.ParamConverterProvider
) を登録する必要があり、オンデマンドでパラメーターコンバーター (型 javax.ws.rs.ext.ParamConverter
) が作成されます。
ParamConverter インターフェイス
javax.ws.rs.ext.ParamConverter
インターフェイスは以下のように定義されます。
// Java package javax.ws.rs.ext; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.ws.rs.DefaultValue; public interface ParamConverter<T> { @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public static @interface Lazy {} public T fromString(String value); public String toString(T value); }
独自の ParamConverter
クラスを実装するには、このインターフェイスを実装し、fromString
メソッド (パラメーター文字列をターゲット型に変換) および toString
メソッド (ターゲット型を文字列に変換) をオーバーライドする必要があります。
ParamConverterProvider interface
javax.ws.rs.ext.ParamConverterProvider
インターフェイスは以下のように定義されます。
// Java package javax.ws.rs.ext; import java.lang.annotation.Annotation; import java.lang.reflect.Type; public interface ParamConverterProvider { public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation annotations[]); }
独自の ParamConverterProvider
クラスを実装するには、このインターフェイスを実装し、ParamConverter
インスタンスを作成するファクトリーメソッドである getConverter
メソッドをオーバーライドする必要があります。
パラメーターコンバータープロバイダーのバインディング
パラメーターコンバータープロバイダーを JAX-RS ランタイムに バインド (アプリケーションで利用可能) するには、以下のように実装クラスに @Provider
アノテーションを付ける必要があります。
// Java ... import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; @Provider public class TargetTypeProvider implements ParamConverterProvider { ... }
このアノテーションを使用することで、パラメーターコンバータープロバイダーがデプロイメントのスキャンフェーズで自動的に登録されるようになります。
例
以下の例は、パラメーター文字列を TargetType
型に変換する機能を持つ ParamConverterProvider
および ParamConverter
を実装する方法を示しています。
// Java import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; @Provider public class TargetTypeProvider implements ParamConverterProvider { @Override public <T> ParamConverter<T> getConverter( Class<T> rawType, Type genericType, Annotation[] annotations ) { if (rawType.getName().equals(TargetType.class.getName())) { return new ParamConverter<T>() { @Override public T fromString(String value) { // Perform conversion of value // ... TargetType convertedValue = // ... ; return convertedValue; } @Override public String toString(T value) { if (value == null) { return null; } // Assuming that TargetType.toString is defined return value.toString(); } }; } return null; } }
パラメーターコンバーターの使用
TargetType
のパラメーターコンバーターを定義したので、パラメーターを TargetType
フィールドおよび引数に直接インジェクトできるようになりました。次に例を示します。
// Java import javax.ws.rs.FormParam; import javax.ws.rs.POST; ... @POST public Response updatePost(@FormParam("target") TargetType target) { ... }
デフォルト値の遅延変換
パラメーターのデフォルト値を指定する場合 ( @DefaultValue
アノテーションを使用して)、デフォルト値がターゲットの型にすぐ変換される (デフォルトの動作) か、必要な場合にのみ変換されるべきか (遅延変換) を選択することができます。遅延変換を選択するには、@ParamConverter.Lazy
アノテーションをターゲット型に追加します。以下に例を示します。
// Java import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.DefaultValue; import javax.ws.rs.ext.ParamConverter.Lazy; ... @POST public Response updatePost( @FormParam("target") @DefaultValue("default val") @ParamConverter.Lazy TargetType target) { ... }