2012-07-03 3 views
12

one of the few questions (with answers)私はJAX-RSとキャッシングに関してSOを見つけましたが、レスポンスオブジェクトにいくつかの値を設定することで、キャッシングのためのETagsを生成することができます。問題は、それは、我々は両方のSOAPのために同じ方法を使用するので、私たちのために働くと@WebMethod(SOAP)を持つメソッドに注釈を付けることで、RESTサービスはありませんResponseオブジェクトに頼らずにJAX-RSを使ってETagsを設定することはできますか?

@GET 
@Path("/person/{id}") 
public Response getPerson(@PathParam("id") String name, @Context Request request){ 
    Person person = _dao.getPerson(name); 

    if (person == null) { 
    return Response.noContent().build(); 
    } 

    EntityTag eTag = new EntityTag(person.getUUID() + "-" + person.getVersion()); 

    CacheControl cc = new CacheControl(); 
    cc.setMaxAge(600); 

    ResponseBuilder builder = request.evaluatePreconditions(person.getUpdated(), eTag); 

    if (builder == null) { 
    builder = Response.ok(person); 
    } 

    return builder.cacheControl(cc).lastModified(person.getUpdated()).build(); 
} 

、@GET(および次のようにサービスを公開するために必要なものは何でも)。以前のサービスは、(ヘッダの作成を除く)私たちに次のようになります。

@WebMethod 
@GET 
@Path("/person/{id}") 
public Person getPerson(@WebParam(name="id") @PathParam("id") String name){ 
    return _dao.getPerson(name); 
} 

どのような方法があります - いくつかの余分な設定を通して - これらのヘッダを設定するの? Responseオブジェクトを使用すると実際には自動変換に比べていくつかの利点があることがわかったのは初めてです...

私たちはApache CXFを使用しています。

+0

何らかのインターセプターを使用できますか? http://stackoverflow.com/questions/3165647/apache-cxf-how-to-add-custom-http-header-to-jax-rs-response?rq=1 – oligofren

答えて

7

はい、レスポンスオブジェクトを作成した後にEタグを生成できる場合は、これを実現するためにインターセプタを使用できます。

public class MyInterceptor extends AbstractPhaseInterceptor<Message> { 

    public MyInterceptor() { 
     super(Phase.MARSHAL); 
    } 

    public final void handleMessage(Message message) { 
     MultivaluedMap<String, Object> headers = (MetadataMap<String, Object>) message.get(Message.PROTOCOL_HEADERS); 

     if (headers == null) { 
      headers = new MetadataMap<String, Object>(); 
     }    

     //generate E-tag here 
     String etag = getEtag(); 
     // 
     String cc = 600; 

     headers.add("E-Tag", etag); 
     headers.add("Cache-Control", cc); 
     message.put(Message.PROTOCOL_HEADERS, headers); 
    } 
} 

その方法が実行可能でない場合、私はあなたが投稿元の溶液を使用し、ちょうどビルダーにごPersonエンティティを追加します。

Person p = _dao.getPerson(name); 
return builder.entity(p).cacheControl(cc).lastModified(person.getUpdated()).build(); 
1

またはそれは、送信と同じくらい簡単ですあなたがしたいことに応じて、 "エラー"コードを戻してください。

@Path("/{id}") 
@GET 
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) 
public ProductSearchResultBean getProductById(@PathParam("id") Integer productId, @QueryParam("expand") List<String> expand, @Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { 

    ProductSearchResultBean productDetail = loadProductDetail(productId, expand); 

    EntityTag etag = new EntityTag(((Integer)(productDetail.toString().hashCode())).toString()); 
    String otherEtag = request.getHeader("ETag"); 
    if(etag.getValue().equals(otherEtag)){ 
     response.sendError(304, "not Modified"); 
    } 

    response.addHeader("ETag", etag.getValue()); 

    return productDetail; 
} 

これは私がどのように発行に取り組んだかです。がんばろう! (代わりにSpring MVCを使用してください...あなたのためにあらゆることをするボックスフィルタがあります...でも良いETagを作っています:))

関連する問題