是否可以使用JAX-RS设置ETag而无需使用Response对象? [英] Is it possible to set ETags using JAX-RS without resorting to Response objects?

查看:176
本文介绍了是否可以使用JAX-RS设置ETag而无需使用Response对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为数不多的问题之一(有答案)我在SO上发现有关JAX-RS和缓存的问题,生成ETag(用于缓存)的答案是在Response对象上设置一些值。如下所示:

In one of the few questions (with answers) I have found on SO regarding JAX-RS and caching, the answer to generating ETags (for caching) is by setting some values on the Response object. As in the following:

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

问题是这对我们不起作用,因为我们使用相同的方法对于SOAP和REST服务,通过使用@WebMethod(SOAP),@ GET(以及我们可能需要公开服务的任何其他内容)来注释方法。以前的服务对我们来说是这样的(不包括标题的创建):

The problem is that will not work for us, since we use the same methods for both SOAP and REST services, by annotating the methods with @WebMethod (SOAP), @GET (and whatever else we might need to expose the service). The previous service would look like this to us (excluding the creation of headers):

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

有没有办法 - 通过一些额外的配置 - 设置这些标题?这是我第一次发现使用Response对象实际上只比自动转换有一些好处...

Is there any way - through some extra configuration - of setting those headers? This is the first time I have found that using Response objects actually has some benefit over just auto-conversion ...

我们正在使用Apache CXF。

We are using Apache CXF.

推荐答案

是的,如果您可以在创建响应对象后生成E-tag,则可以使用拦截器实现此目的。

Yes you might be able to use interceptors to achieve this if you could generate the E-tag AFTER you create your response object.

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实体添加到构建器:

If that way isn't viable, I would use the original solution that you posted, and just add your Person entity to the builder:

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

这篇关于是否可以使用JAX-RS设置ETag而无需使用Response对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆