2012-07-03 30 views
12

Trong one of the few questions (with answers) Tôi đã tìm thấy trên SO liên quan đến JAX-RS và bộ nhớ đệm, câu trả lời để tạo ra ETags (cho bộ nhớ đệm) là bằng cách thiết lập một số giá trị trên đối tượng Response. Như trong những điều sau đây:Có thể đặt ETags bằng JAX-RS mà không cần sử dụng đối tượng Response không?

@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(); 
} 

Vấn đề là sẽ không làm việc cho chúng ta, vì chúng ta sử dụng phương pháp tương tự cho cả hai SOAP và REST dịch vụ, bằng cách chú thích các phương pháp với @WebMethod (SOAP), @GET (và bất cứ điều gì khác chúng ta có thể cần để lộ dịch vụ). Dịch vụ trước đó sẽ trông giống như thế này cho chúng tôi (không bao gồm việc tạo tiêu đề):

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

Có cách nào - thông qua một số cấu hình bổ sung - để đặt các tiêu đề đó không? Đây là lần đầu tiên tôi nhận thấy rằng việc sử dụng các Đối tượng phản hồi thực sự có một số lợi ích chỉ là tự động chuyển đổi ...

Chúng tôi đang sử dụng Apache CXF.

+0

Tôi có thể sử dụng một số loại Interceptor không? http://stackoverflow.com/questions/3165647/apache-cxf-how-to-add-custom-http-header-to-jax-rs-response?rq=1 – oligofren

Trả lời

7

Có, bạn có thể sử dụng bộ chặn để đạt được điều này nếu bạn có thể tạo thẻ E SAU KHI bạn tạo đối tượng phản hồi của mình.

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); 
    } 
} 

Nếu như vậy là không khả thi, tôi sẽ sử dụng các giải pháp ban đầu mà bạn được đăng, và chỉ cần thêm thực thể Person của bạn để xây dựng:

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

hoặc nó có thể đơn giản như gửi trở lại một "lỗi" mã ... tùy thuộc vào những gì bạn muốn làm.

@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; 
} 

Đó là cách tôi giải quyết issure anyway. Chúc may mắn! (Sử dụng Spring MVC thay vào đó .... có một bộ lọc hộp có thể làm mọi thứ cho bạn ... thậm chí tạo ra một ETag tốt :))

Các vấn đề liên quan