CXF no implementa el filtrado dinámico como se explica aquí: http://www.jalg.net/2012/09/declarative-cache-control-with-jax-rs-2-0
Y si se utiliza para volver directamente a sus propios objetos y no CXF respuesta, es difícil añadir una cabecera de control de caché.
Encuentro una manera elegante mediante el uso de una anotación personalizada y la creación de un Interceptor CXF que lee esta anotación y agrega el encabezado.
Así que en primer lugar, crear una anotación CacheControl
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheControl {
String value() default "no-cache";
}
A continuación, añadir esta anotación a su método de operación CXF (interfaz o aplicación que funciona tanto si se utiliza una interfaz)
@CacheControl("max-age=600")
public Person getPerson(String name) {
return personService.getPerson(name);
}
Entonces crea un interceptor CacheControl que manejará la anotación y agregará el encabezado a tu respuesta.
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()));
}
}
Finalmente configurar CXF para utilizar su interceptor, se puede encontrar toda la información necesaria aquí: http://cxf.apache.org/docs/interceptors.html
esperan que ayude.
Loïc
Great answer. Mi único comentario es que la EntityTag que generas probablemente no necesita el UUID de la persona. Solo es importante que un eTag cambie entre las revisiones del mismo recurso. Suponiendo que la ID es inmutable, UUID es redundante con la ruta al recurso (aunque su Impl llama a ese parámetro "nombre", por lo que tal vez no sea inmutable. Además, debe asegurarse de que este valor sea específico de la representación. dos representaciones de un recurso varían según el tipo de medio, utilice el valor de tipo de medio junto con el identificador de versión para crear un valor ETag específico de representación. – benvolioT
Nunca utilizo un objeto Response; simplemente deje que CXF maneje esa parte. ¿Cómo lo haría? sin él? – oligofren
@oligofren Nunca los había usado antes, pero esa fue la única solución que encontré. – sfussenegger