17

CXF文档提到缓存为Advanced HTTP

CXF JAXRS 通过处理 If-Match、If-Modified-Since 和 ETags 标头提供对许多高级 HTTP 功能的支持。JAXRS 请求上下文对象可用于检查先决条件。还支持 Vary、CacheControl、Cookies 和 Set-Cookies。

我对使用(或至少探索)这些功能非常感兴趣。然而,虽然“提供支持”听起来很有趣,但它对于实现这些功能并不是特别有帮助。有关如何使用 If-Modified-Since、CacheControl 或 ETags 的任何帮助或指示?

4

3 回答 3

27

实际上,答案并不特定于 CXF - 它是纯 JAX-RS:

// IPersonService.java
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;

@GET
@Path("/person/{id}")
Response getPerson(@PathParam("id") String id, @Context Request request);


// PersonServiceImpl.java
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

public Response getPerson(String name, 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();
}
于 2010-01-19T09:24:33.993 回答
5

如http://jalg.net/2012/09/declarative-cache-control-with-jax-rs-2-0/中所述,随着即将推出的 JAX-RS 2.0,可以以声明方式应用 Cache-Control

您至少可以使用 Jersey 进行测试。虽然不确定 CXF 和 RESTEasy。

于 2012-09-24T22:05:45.573 回答
0

CXF 没有实现动态过滤,如下所述:http ://www.jalg.net/2012/09/declarative-cache-control-with-jax-rs-2-0

而且,如果您使用直接返回自己的对象而不是 CXF 响应,则很难添加缓存控制标头。

我通过使用自定义注释并创建读取此注释并添加标题的 CXF 拦截器找到了一种优雅的方式。

所以首先,创建一个 CacheControl 注解

@Target(ElementType.METHOD )
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheControl {
    String value() default "no-cache";
}

然后,将此注释添加到您的 CXF 操作方法(如果您使用接口,则它适用于两者的接口或实现)

@CacheControl("max-age=600")
public Person getPerson(String name) {
    return personService.getPerson(name);
}

然后创建一个 CacheControl 拦截器来处理注释并将标头添加到您的响应中。

public class CacheInterceptor extends AbstractOutDatabindingInterceptor{
    public CacheInterceptor() {
        super(Phase.MARSHAL);
    }

    @Override
    public void handleMessage(Message outMessage) throws Fault {
        //search for a CacheControl annotation on the operation
        OperationResourceInfo resourceInfo = outMessage.getExchange().get(OperationResourceInfo.class);
        CacheControl cacheControl = null;
        for (Annotation annot : resourceInfo.getOutAnnotations()) {
            if(annot instanceof CacheControl) {
                cacheControl = (CacheControl) annot;
                break;
            }
        }

        //fast path for no cache control
        if(cacheControl == null) {
            return;
        }

        //search for existing headers or create new ones
        Map<String, List<String>> headers = (Map<String, List<String>>) outMessage.get(Message.PROTOCOL_HEADERS);
        if (headers == null) {
            headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
            outMessage.put(Message.PROTOCOL_HEADERS, headers);
        }

        //add Cache-Control header
        headers.put("Cache-Control", Collections.singletonList(cacheControl.value()));
    }
}

最后配置 CXF 使用你的拦截器,你可以在这里找到所有需要的信息:http: //cxf.apache.org/docs/interceptors.html

希望它会有所帮助。

洛伊克

于 2018-02-08T11:18:14.143 回答