Red Hat Training
A Red Hat training course is available for Red Hat Fuse
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)
{
...
}