1

タイトルが正しいことを願ってい@Pathますが、エンティティ パラメーターに基づいて、JAX-RS アノテーションを使用してリクエストをさまざまなメソッドにマップしようとしています。

サンプルコードで簡単になると思います:

スーパークラス:

public class Geothing {
    private int thingId;
    private String status;

    // Ctor, getters and setters
}

PolygonGeothing は Geothing を拡張します。

@XmlRootElement
public class PolygonGeothing extends Geothing {
    private Coordinates coordinates;

    // Ctor, getters and setters
}

CircleGeothing は Geothing を拡張します。

@XmlRootElement
public class CircleGeothing extends Geothing {
    private Coordinate center;
    private int radius;

    // Ctor, getters and setters
}

サービス インターフェイス:

@Path("/geothing/{id}")
public interface GeothingService extends CoService {
    @POST
    Response createGeothing(@PathParam("{id}") Long id, PolygonGeothing geothing);

    @POST
    Response createGeothing(@PathParam("{id}") Long id, CircleGeothing geothing);
}

PolygonGeothing または CircleGeothing の XML を POST した場合、それが機能することを期待していました。ただし、PolygonGeothing XML を POST した場合にのみ機能し、CircleGeothing XML を POST すると JAXBException が発生します。
JAXBException occurred : unexpected element (uri:"", local:"circleGeothing"). Expected elements are <{}polygonGeothing>.

CircleGeothing と PolygonGeothing に別の URI パスを指定しなくても、これを正しくマッピングすることは可能ですか? さらに、スーパークラスをパラメータとして使用できる次のようなインターフェースを持つことは可能ですか? 返されるタイプ Geothing をテストしました。PolygonGeothing または CircleGeothing を作成して返すと、正常に動作します...ただし、パラメータ タイプが Geothing であるパラメータとして PolygonGeothing または CircleGeothing を渡そうとすると、うまくいきません。

@Path("/geothing/{id}")
public interface GeothingService extends CoService {
    @POST
    Response createGeothing(@PathParam("{id}") Long id, Geothing geothing);
}
4

1 に答える 1

1

このようにすることは不可能です。理由は簡単です。CXF (他の JAX-RS フレームワークと同様) は、オブジェクト指向のプリンシパルではなく、REST 定義に基づいて応答をルーティングします。つまり、URL、生成されたコンテンツ タイプ、および消費されたコンテンツ タイプに基づいてメソッドを選択します。(これは簡単な説明です。正確なアルゴリズムについては、JSR311 を参照してください)。しかし、それはあなたが期待するオブジェクトとは何の関係もありません。オブジェクトは、メソッドが既に選択された後にのみシリアル化されます。これが例外が発生する理由です:createGeothing(@PathParam("{id}") Long id, PolygonGeothing geothing)が選択されているため、間違ったクラスをシリアル化しようとします。

次のことができます。

Response createGeothing(@PathParam("{id}") Long id, Geothing geothing)

そして、関連するメソッドをキャストして呼び出します。
もちろん、 Geothing が JAXB コンテキストに認識されていることを確認する必要があります。

于 2011-02-03T07:08:52.280 に答える