CXF không thực hiện lọc động như đã giải thích ở đây: http://www.jalg.net/2012/09/declarative-cache-control-with-jax-rs-2-0
Và nếu bạn sử dụng để quay trở lại trực tiếp đối tượng của riêng bạn và không CXF đáp ứng, thật khó để thêm một tiêu đề kiểm soát bộ nhớ cache.
Tôi tìm một cách thanh lịch bằng cách sử dụng chú thích tùy chỉnh và tạo Bộ chặn đánh dấu CXF đọc chú thích này và thêm tiêu đề.
Vì vậy, đầu tiên, tạo ra một chú thích CacheControl
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheControl {
String value() default "no-cache";
}
Sau đó, thêm chú thích này để CXF phương pháp hoạt động của bạn (giao diện hoặc thực hiện nó hoạt động trên cả hai nếu bạn sử dụng một giao diện)
@CacheControl("max-age=600")
public Person getPerson(String name) {
return personService.getPerson(name);
}
Sau đó, tạo ra một bộ chặn đánh chặn CacheControl sẽ xử lý chú thích và thêm tiêu đề vào phản hồi của bạn.
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()));
}
}
Cuối cùng cấu hình CXF sử dụng đánh chặn, bạn có thể tìm thấy tất cả các thông tin cần thiết ở đây: http://cxf.apache.org/docs/interceptors.html
Hy vọng nó sẽ giúp.
Loïc
Câu trả lời hay. Nhận xét duy nhất của tôi là EntityTag bạn tạo ra có lẽ không cần UUID của người đó. Điều quan trọng là thay đổi eTag giữa các phiên bản của cùng một tài nguyên. Giả sử ID là không thay đổi, UUID là dự phòng với đường dẫn đến tài nguyên (mặc dù Impl của bạn gọi tham số đó là "name", vì vậy có lẽ nó không phải là bất biến. Ngoài ra, bạn nên đảm bảo rằng giá trị này là đại diện cụ thể. Ví dụ, nếu hai biểu diễn của một tài nguyên thay đổi theo loại phương tiện truyền thông, sử dụng giá trị loại phương tiện truyền thông cùng với định danh phiên bản để tạo ra một giá trị ETAG đại diện cụ thể – benvolioT
Tôi không bao giờ sử dụng một đối tượng Response - chỉ cần để CXF xử lý phần đó. không có nó? – oligofren
@oligofren Tôi chưa bao giờ sử dụng chúng bản thân mình trước đây nhưng đó là giải pháp duy nhất tôi tìm thấy – sfussenegger