5

JAX-RS は、 でコンテンツ タイプを指定する素晴らしい方法を提供します@Produces。フレームワークは、クライアントの HTTP ヘッダーから最適なコンテンツ タイプを自動的に決定し、Accept驚くべきことに、オブジェクトをそのタイプに変換します (たとえば、JAXB を使用する XML または Jackson を使用する JSON)。 ) 呼び出し元に情報を返すとき。

私の(仕事の)クライアントは、クライアントがよくするように、URL の拡張子でコンテンツ タイプを指定するように要求することで、単純な仕事をより困難にしましたapi/widgets.json。これにより、 を使用したもの、 を使用したものなど、さまざまなgetWidgetsXXX()方法が必要になります。@Produces("application/json")@Produces("application/xml")

しかし、私は Apache CXF を使用しており、CXF を構成jaxrs.extensionsして、 init パラメータを使用してさまざまな拡張機能をコンテンツ タイプにマップできることを発見してうれしく思いました。

<!-- registers extension mappings -->
<init-param>
  <param-name>jaxrs.extensions</param-name>
  <param-value>
    xml=application/xml
    json=application/json
  </param-value>
</init-param>

しかし、これが現実の世界でどのように機能するかについてのドキュメントはまったく見つかりません。メソッドに拡張子付きのパスで注釈を付けるだけで、Acceptsヘッダーを模倣できると単純に考えました。

@Path("/widgets.{extension}")
@GET
@Produces({ "application/json", "application/xml" })
public List<Widget> getWidgets();

を使用して呼び出すとapi/widgets.json、XML が返されます。JAX-RS では、デフォルトのコンテンツ タイプがリストの最初にあると指定されているため、これは特に奇妙です。

CXF 拡張コンテンツ タイプ マッピングの使用方法はどこで確認できますか?

PS私はSpringを使用していません。

4

4 に答える 4

4

<jaxrs:server>あなたの作品に以下を追加してください:

<jaxrs:extensionMappings>
    <entry key="json" value="application/json" />
    <entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>

ソース: http://cxf.apache.org/docs/jax-rs.html#JAX-RS-Debugging

于 2012-04-27T11:55:09.713 に答える
1

それが役立つかどうかはわかりませんが、JAX-RSサービスにそのようなものを導入するために同じ問題に直面していました。JAX-RS_Content_Negotiationを使用してこの機能を実現しました。次の場所に詳細があります。

https://docs.jboss.org/resteasy/docs/3.0.6.Final/userguide/html/JAX-RS_Content_Negotiation.html

メディアタイプを必要な値にマップするだけです

 <context-param>
        <param-name>resteasy.media.type.mappings</param-name>
        <param-value>
          html : text/html, json : application/json, xml :           
           application/xml
       </param-value>
 </context-param>


 @GET
        @Path("/second/{param}")
        @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
        public Response printStudent(@PathParam("param") String msg) {


}

今、私はそのようなサービスにアクセスでき、応答は最後に付けた拡張子に従っています

http://localhost:8080/RESTfulExample/rest/message/second/bill.json

URL の末尾に .xml または .json を配置すると、サービスはそれに応じて応答を生成します。

于 2016-06-21T22:23:06.967 に答える
0

あなたの状況では、メソッド @Produces コンテンツ タイプ*/*(つまり、完全なワイルドカード) を宣言してから、自分でコンテンツ ネゴシエーションを行います。おそらく、次のようなメソッド シグネチャを見ているでしょう。

@javax.ws.rs.GET
@javax.ws.rs.Path("{filename}")
@javax.ws.rs.Produces("*/*")
javax.ws.rs.core.Response getDirectoryOrFileContents(
        @javax.ws.rs.PathParam("filename") String filename,
        @javax.ws.rs.core.Context javax.ws.rs.core.HttpHeaders headers);

これにより、目的のファイル名 (配信するメディア タイプを推測する方法の 1 つ) と、HTTP ヘッダーの完全なセット (ヒント: use を使用) の両方にアクセスできますheaders.getAcceptableMediaTypes()。両者のバランスをどう取るかが「面白さ」になりそうです。(私がしなければならないコードは、私のアプリの内部モデルに非常に固有のものであるため、役に立たない可能性があります。) 次に、 を作成して結果を返しますResponse。帰る。

はい、これは CXF にこれらすべてを処理させるよりも手間がかかります (通常、これらすべてを実行するために多くのボイラープレートが生成されます) が、複雑なケースでは制御に満足するでしょう。

于 2012-04-06T21:21:12.083 に答える