4

プロジェクトの抽象クラスであり、データベースに格納されている動物を操作するAnimalためのRESTリソース(JAX-RSサーバー上にJacksonを(逆)シリアル化に使用)があるとします。PUTそれらには具体的なタイプがあり、RESTリソースはリクエストのパスでタイプを指定します。

@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{entityType}/{id: \\d+}")
public <T extends Animal> void putAnimal(@PathParam("entityType") String entityType, @PathParam("id") String id, Animal input) throws IOException {
    //...
}

entityTypeデシリアライズする具象クラスを選択するために使用したいと思います(DogまたはCat、または何でも、存在するためentityTypedogまたはcat何でも)。ここで説明するには複雑すぎるため、JSON入力自体に型情報を入れることはできません。

したがって、AIUIAnimalがカスタムTypeIdResolverなどで注釈を付けることは、型情報がJSON自体に含まれないため(そして型リゾルバーが取得するすべての情報であるため)、役に立ちません。カスタムを使用することを計画していましたMessageBodyReaderが、私が知る限り、メソッドで渡された本体から他のパラメーター値を取得しないため、readValue何にデシリアライズするかわかりません。

私は何が欠けていますか?このアプローチが失敗した場合、動物固有のエンドポイントを指定せずに、どのように私が望むことを達成できますか(これは、多くの重複コードと一般性の喪失につながります-今、私はのサブクラスを追加でき、Animalこのコードは正しく機能します、これとてもいいです。)

4

2 に答える 2

4

JAX-RS仕様(5.2.2 URIおよびURIテンプレート)からの以下の引用は、UriInfoインスタンスをカスタムに挿入しMessageBodyReader、そのメソッドの1つを使用してリクエストのURLパスを検査できる必要があることを示しています。

UriInfoのインスタンスは、@Context注釈を使用してクラスフィールドまたはメソッドパラメーターに挿入できます。UriInfoは、リクエストURIのコンポーネントに関する、静的および動的の両方のリクエストごとの情報を提供します。

そこに提供されている例は、パラメーターを受け取るリソースメソッドを示していますが、通常は、プロバイダー( )にもUriInfoインスタンスを注入できるはずです。MessageBodyReader

entityTypeを介してパスパラメータを取得した後、対応するのサブクラスを提供できるようになりUriInfoます。MessageBodyReaderAnimal

于 2013-03-01T16:22:52.497 に答える
0

あなたがやろうとしていることを考えるとAnimalResource、基本的なメソッドを含むクラスを構築してから、個別に構築することDogResourceCatResourceおよびを拡張する必要な他のクラスを構築することをお勧めしますAnimalResource。これにより、の正しいサブクラスを取得できるAnimalため、入力JSONを正しく逆シリアル化できます。

更新 これがどのように達成されるかの例。基本リソースは次のようになります。

public class AnimalResource<T extends Animal>
{
    private final transient AnimalService<T> service;

    public AnimalResource(final AnimalService<T> service)
    {
        this.service = service;
    }

    @Get
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public T getbyId(@PathParam("id") final String id)
    {
        return this.service.findById(id);
    }

    // Other CRUD methods go here
}

そして、あなたの個々の動物は、それらがすべて同じ設定をしていると仮定すると、単純に次のようになります。

@Path("/cats")
public class CatResource extends AnimalResource<Cat>
{
    public CatResource(final CatService catService)
    {
        super(catService);
    }
}

猫と

@Path("/dogs")
public class DogResource extends AnimalResource<Dog>
{
    public DogResource(final DogService dogService)
    {
        super(dogService);
    }
}

犬のために。それらは親から標準のCRUDメソッドを継承し、動物固有のメソッドは引き続き個々の*Resourceクラスに入れることができます。

于 2013-03-01T16:34:58.260 に答える