6

いくつかのサブリソースを持つJAX-RSサービス(MyService)を作成しました。各サブリソースは、MySubResourceのサブクラスです。選択されるサブリソースクラスは、MyServiceパスで指定されたパラメータに基づいて選択されます。次に例を示します。

@Path("/") @Provides({"text/html", "text/xml"}) 
public class MyResource {
  @Path("people/{id}") public MySubResource getPeople(@PathParam("id") String id) {
    return new MyPeopleSubResource(id);
  }
  @Path("places/{id}") public MySubResource getPlaces(@PathParam("id") String id) {
    return new MyPlacesSubResource(id);
  }
}

ここで、MyPlacesSubResourceとMyPeopleSubResourceはどちらもMySubResourceのサブクラスです。

MySubResourceは次のように定義されます。

public abstract class MySubResource {
  protected abstract Results getResults();

  @GET public Results get() { return getResults(); }

  @GET @Path("xml") 
  public Response getXml() {
    return Response.ok(getResults(), MediaType.TEXT_XML_TYPE).build();  
  }

  @GET @Path("html") 
  public Response getHtml() {
    return Response.ok(getResults(), MediaType.TEXT_HTML_TYPE).build();  
  }
}

結果は、応答のmimetypeに応じて、対応するMessageBodyWritersによって処理されます。

これは機能しますが、/ people / Bob/htmlや/people/ Bob / xmlのようなパスになります。ここで、私が本当に必要としているのは/people/Bob.htmlまたは/people/Bob.xmlです。

誰かが私がやりたいことを達成する方法を知っていますか?

4

4 に答える 4

7

古いトピックですが、これは最近ジャージーを使用して解決したものです。多分それは他の誰かを助けるでしょう。

Jerseyは、リクエストフィルタを使用して、受け入れられたコンテンツタイプをURIのファイル拡張子として指定することをサポートしています。Jerseyは、UriConnegFilter特定の拡張機能をコンテンツタイプに変換するために拡張する(URIコンテンツネゴシエーションフィルター)オブジェクトを提供します。次に、そのフィルターをJerseyアプリケーションの初期パラメーターとして含めます。

それはすべてとても曖昧に聞こえるので、これが私のプロジェクトからの具体的な例です:

URLの最後にある「.json」と「.xml」を、クライアントがそれぞれJSON形式またはXML形式のコンテンツを必要としていることを意味するものとして解釈できるようにしたかったのです。UriConnegFilterそのために、私はそのように拡張しました:

package my.filter.package;

import com.sun.jersey.api.container.filter.UriConnegFilter;

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

import javax.ws.rs.core.MediaType;


public class MediaTypeFilter extends UriConnegFilter {
  private static final Map<String, MediaType> mappedMediaTypes = new HashMap<String, MediaType>(2);

  static {
    mappedMediaTypes.put("json", MediaType.APPLICATION_JSON_TYPE);
    mappedMediaTypes.put("xml", MediaType.APPLICATION_XML_TYPE);
  }

  public MediaTypeFilter() {
    super(mappedMediaTypes);
  }
}

次に、サーブレットとしてJerseyを使用しているMediaTypeFilterため、web.xmlに次のように追加しました。

<servlet>
  <servlet-name>My Jersey Servlet</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>my.resource.package</param-value>
  </init-param>
  <init-param>
    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
    <param-value>com.sun.jersey.api.container.filter.LoggingFilter;
                 my.filter.package.MediaTypeFilter;
                 com.sun.jersey.api.container.filter.PostReplaceFilter;
                 com.sun.jersey.api.container.filter.GZIPContentEncodingFilter</param-value>
  </init-param>
  <init-param>
    <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
    <param-value>com.sun.jersey.api.container.filter.GZIPContentEncodingFilter;
                 com.sun.jersey.api.container.filter.LoggingFilter</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

これで、JerseyはURIの拡張子を指定されたメディアタイプに変換し、拡張子を削除します。これは、URI全体で動作するため、ルートリソースとサブリソースで機能します。特定の例では、/ people/Bob.xmlは/people/ BobになりAccept、リクエストのヘッダーは「application / xml」に変更されます(既存のAcceptヘッダーをオーバーライドします)。

hth、

-ピーター

于 2012-01-06T23:18:52.740 に答える
1

それを解決するために、サーブレットルーティングを作成することもできます。ただし、現実的には、これを行うにはコンテンツタイプを使用する必要があります。

@GET @Path("/") @Produces(MediaType.APPLICATION_XML)
public Response getXml() { ... }

@GET @Path("/") @Produces(MediaType.APPLICATION_HTML)
public Response getHtml() { ... }

次に、JAX-RSプロバイダーは、クライアントの要求に基づいて何を呼び出すかを決定します。さらに良いことに、JAXBとRestEASYを使用してすべてを実行できます。

@GET
@Produces(MediaType.APPLICATION_XML)
@Path("/{id}")
public MyObject getXml(@PathParam("typeDocument") String id) {
 myObjectService.get(id);
}


@XmlRootElement(name="myObject")
public class MyObject {
// Some properties
}

Springの良い例については、http://java.dzone.com/articles/resteasy-springを参照してください。

于 2010-06-03T11:11:23.040 に答える
1

これを解決する1つの方法は、おそらく@javax.ws.rs.Pathで正規表現キャプチャを使用できることです。

@Path("people/{id:[^/]+?}{format:(\\.[^/]*?)?}")
@GET
public MySubResource getPeople(@PathParam("id") String id, @PathParam("format") String format) {
    // remove the "." from the start of "format" if it is not null
    return new MySubResource(id, format);
}

次に、サブリソースで:

public abstract class MySubResource {
    final protected String format;

    protected MySubResource(String id, String format) {
        this.format = format;
    }

    protected abstract Results getResults();

    @GET
    public Response get() {
       return Response.ok(getResults(), this.format).build();  
    }
}

正規表現に注意してください。例を挙げましたが、何もすり抜けないように表現を厳しくすることをお勧めします。

これを解決する別の方法は、{id}がキャプチャされる場所を変更し、そこで正規表現を使用することです。IDをキャプチャする代わりに@Path("id") MySubResource public getPeople(@PathParam("id") String id)、getPeople()からIDキャプチャを削除し、次のようにMySubResourceを変更します。

 @Path("people")
 public MySubResource getPeople() {
    return new MyPeopleSubResource();
 }

public abstract class MySubResource {
  protected abstract Results getResults();

  @GET
  @Path("{id}")
  public Results get() { return getResults(); }

  @GET
  @Path("{id}.xml") 
  public Response getXml() {
    return Response.ok(getResults(), MediaType.TEXT_XML_TYPE).build();  
  }

  @GET
  @Path("{id}.html") 
  public Response getHtml() {
    return Response.ok(getResults(), MediaType.TEXT_HTML_TYPE).build();  
  }
}

どちらの場合も、データ構造がどのように編成されているか、および「id」パラメーターを知る必要がある場合に応じて、トレードオフがあります。正規表現は本当に正しく理解するのが難しいので、私は特に好きではありませんが、この場合は可能性があります。

于 2010-07-20T01:22:25.657 に答える
1

これは古いトピックであり、あなたはこれを理解していると確信していますが、このページにアクセスする人のために、Resteasyはあなたが必要なものを達成する簡単な方法を持っています。これは、URLベースのコンテンツネゴシエーションと呼ばれます。

詳細はこちらをご覧ください:http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html#media_mappings

基本的に、Web.xmlファイルにコンテキストパラメータを追加して、URLのサフィックスを特定のコンテンツタイプにマップするようにResteasyに指示する必要があります。

<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>

これにより、/ people / Bob.xmlにアクセスすることは、/ people / Bobにアクセスし、Accept-Encoding:application/xmlを指定することと同じです。

于 2011-03-24T08:54:16.770 に答える