Menu Close

47.3. パラメーターコンバーター

概要

パラメーターコンバーターを使用すると、パラメーター (String 型の) をフィールド、Bean プロパティー、またはリソースメソッド引数の 任意 の型に注入することができます。適切なパラメーターコンバーターを実装してバインディングし、JAX-RS ランタイムを拡張し、パラメーター String 値をターゲット型に変換できるようにできます。

自動変換

パラメーターは String のインスタンスとして受信されるため、String 型のフィールド、Bean プロパティー、およびメソッドパラメーターに常に注入することができます。さらに、JAX-RS ランタイムには、パラメーター文字列を以下の型に自動的に変換する機能があります。

  1. プリミティブ型。
  2. 単一の String 引数を受け入れるコンストラクターを持つ型。
  3. 型のインスタンスを返す String 引数が 1 つあり、valueOf または fromString という名前の静的メソッドを持つ型。
  4. 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 インターフェース

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)
{
  ...
}

デフォルト値の遅延変換 (Lazy conversion)

パラメーターのデフォルト値を指定する場合 (@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)
{
  ...
}