10

ユーザーがなどbirdのURL パラメータを転送できる (または転送できない) Web API があります。dog

このパラメーターをサーバー側の列挙型にマップする必要があります。次のようなものです。

@POST
@Path("/zoo")
public Response createNewAnimal(
                        @QueryParam("animal") 
                        @DefaultValue("CAT") AnimalType type 
                ) throws Exception 

...

public enum AnimalType {
    BIG_BIRD,
    SMALL_CAT;
}

しかし、それはうまくいきません!

Web リクエストの処理中に、Enum.valueOf()が呼び出されています。もちろん、そのユーザーが URL パラメーターとして使用するパラメーターが( )bird内の識別子と一致しないため、失敗します。EnumAnimalType.BIG_BIRD

メソッドをオーバーライドするvalueOf()方法はなく (静的です...)、コンストラクターを設定しても役に立ちません (論理方向が逆です)。

if...else... を使用する代わりに、これに対する優れた解決策を知っているかもしれません。

4

2 に答える 2

17

次のような列挙型がある場合:

public enum AnimalType {
    BIG_BIRD, 
    SMALL_CAT, 
    MEDIUM_DOG;
}

?animal=BIG_BIRD次に、JAX-RS が返すインスタンスを認識できるようにするには、クエリ パラメータを、?animal=SMALL_CAT またはにする必要があります ?animal=MEDIUM_DOG

クエリ パラメータの値がvalueOf列挙型の静的メソッドに渡され、インスタンスが取得されます。もちろん、次のようなものを送信するbirdと、何にも一致せず、次のことが@QueryParam期待されるため機能しません。

注釈付きのパラメーター 、フィールド、またはプロパティの型 T は、次のいずれかでなければなりませ
ん 。 valueOf(String)) - List、Set、または SortedSet で、T は上記の 2 または 3 を満たします。結果のコレクションは読み取り専用です。


について@DefaultValueも同様です。@DefaultValue("BIG_BIRD")@DefaultValue("SMALL_CAT") または@DefaultValue("MEDIUM_DOG"):を指定する必要があります。

@POST
@Path("/zoo")
public Response createNewAnimal(
        @QueryParam("animal") 
        @DefaultValue("SMALL_CAT") AnimalType type) {
    // ...
    return Response.ok().entity(type.toString()).build();
}

Java 型の名前をクライアントに公開したくない場合は、適切なクエリ文字列値を列挙型インスタンスに変換できます。if ... else ... if はこれを実現するための非常に簡単な方法ですが、より手の込んだものが必要な場合は、次のようなラッパーを作成できます。

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class AnimalTypeWrapper {
    private static final Map<String, AnimalType> MAPPER = Collections
            .unmodifiableMap(new HashMap<String, AnimalType>() {
                {
                    put("bird", AnimalType.BIG_BIRD);
                    put("dog", AnimalType.MEDIUM_DOG);
                    put("cat", AnimalType.SMALL_CAT);
                }
            });

    private AnimalType type;

    public static AnimalTypeWrapper valueOf(String value) {
        AnimalType type = AnimalTypeWrapper.MAPPER.get(value.toLowerCase());
        if (type == null) {
            // if nothing found just set the desired default value
            type = AnimalType.SMALL_CAT;
        }
        return new AnimalTypeWrapper(type);
    }

    private AnimalTypeWrapper(AnimalType type) {
        this.type = type;
    }

    public AnimalType getType() {
        return this.type;
    }
}

リソースメソッドには次のものがあります。

@POST
@Path("/zoo")
public Response createNewAnimal(
        @QueryParam("animal") 
        AnimalTypeWrapper typeWrapper) {
    // ...
    AnimalType type = typeWrapper.getType();
    return Response.ok().entity(type.toString()).build();
}
于 2013-02-09T10:47:03.503 に答える