Frage

Das CXF Dokumentation erwähnt, wie Erweitertes HTTP:

CXF JAXRS unterstützt eine Reihe fortschrittlicher HTTP-Funktionen durch Handhabung von IF-Match-, IF-Modified-Since- und ETAGS-Headern. JAXRS Request Context -Objekt kann verwendet werden, um die Voraussetzungen zu überprüfen. Variieren Sie auch CacheControl, Cookies und Set-Cookies.

Ich bin sehr daran interessiert, diese Funktionen zu verwenden (oder zumindest zu erkunden). Obwohl "Support" wirklich interessant klingt, ist es jedoch nicht besonders hilfreich bei der Implementierung solcher Funktionen. Irgendwelche Hilfe oder Zeiger, wie man if-modifizierte Since, Cachecontrol oder ETAGs verwendet?

War es hilfreich?

Lösung

Tatsächlich ist die Antwort nicht spezifisch für CXF - es ist reines 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();
}

Andere Tipps

Mit dem bevorstehenden JAX-RS 2.0 wird es möglich sein, das Cache-Kontroll deklarativ anzuwenden, wie in erläutert http://jalg.net/2012/09/declarative-cache-control-with-jax-rs-2-0/

Sie können dies bereits zumindest mit Jersey testen. Ich bin mir jedoch nicht sicher über CXF und Resteasy.

CXF implementiert keine dynamische Filterung, wie hier erläutert: http://www.jalg.net/2012/09/declarative-cache-control-with-jax-rs-2-0

Und wenn Sie Ihre eigenen Objekte direkt zurückgeben und nicht die CXF -Antwort, ist es schwierig, einen Cache -Steuerkopf hinzuzufügen.

Ich finde einen eleganten Weg, indem ich eine benutzerdefinierte Annotation verwende und einen CXF -Interceptor erstelle, der diese Annotation liest und den Header hinzufügt.

Erstellen Sie zuerst eine CacheControl -Annotation

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

Fügen Sie dann diese Annotation Ihrer CXF -Betriebsmethode hinzu (Schnittstelle oder Implementierung. Sie funktioniert beider, wenn Sie eine Schnittstelle verwenden).

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

Erstellen Sie dann einen CacheControl -Interceptor, der die Annotation behandelt, und fügen Sie den Header Ihrer Antwort hinzu.

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

Konfigurieren Sie schließlich CXF, um Ihren Interceptor zu verwenden. Hier finden Sie alle erforderlichen Informationen: http://cxf.apache.org/docs/interceptors.html

Hoffe es wird helfen.

Loïc

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top