2011-11-29 15 views
9

Jersey kaynakları üzerinde ek açıklamalar ile etkileşim iki dersleri sunmaktadır: Uygulama başladığında bir kez tetiklenmesinasıl kaynak açıklamaları alabileceğiniz bir Jersey ContainerResponseFilter

ResourceFilterFacto ry, yöntem ve sınıf ek açıklamalarına erişim sağlayan bir AbstractMethod alan bir create yöntemini (uygulamak için) tanımlar.

ContainerRequestFilter ve ContainerResponseFilter tanımlayan bir filter yöntem istek/tepkiyi almak ancak bu denilen yöntem açıklama münhasıran erişimi değil, sınıf birini veririz ki (uygulamak).

HTTP önbellek başlıklarını aşağıdaki şekilde tanımlayan bir CacheControl ek açıklaması yapmaya çalışıyorum.

@Path("/path") 
@CacheControl(maxAge = 172800) 
public class Resource 
{ 
    @GET 
    @Path("/{id}") 
    @CacheControl(mustRevalidate = true) 
    public Response get(@PathParam("id") Long id) 
    { 
     ... 
    } 
} 

Benim sorunum

benim uygulamada tanımlanan her DİNLENME yöntemi için yeni bir CacheControlFilter oluşturmak istediğiniz kalmamasıdır.

public class FilterFactory implements ResourceFilterFactory 
{  
    @Override 
    public List<ResourceFilter> create(AbstractMethod method) 
    { 
     List<ResourceFilter> filters = newArrayList(); 
     if (isAnnotationPresent(method, CacheControl.class)) 
      filters.add(new CacheControlFilter(method)); 
     return filters; 
    } 

    private boolean isAnnotationPresent(AbstractMethod method, Class<? extends Annotation> clazz) 
    { 
     return method.isAnnotationPresent(clazz) || method.getResource().isAnnotationPresent(clazz); 
    } 
} 

her DİNLENME yöntemi için bir CacheContronlFilter örneklilik olmadan AbstractMethod erişmek için bir yolu var mı?

public class CacheControlFilter implements ResourceFilter, ContainerResponseFilter 
{ 
    private AbstractMethod method; 

    public CacheControlFilter(AbstractMethod method) 
    { 
     this.method = method; 
    } 

    @Override 
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) 
    { 
     putCacheControlIfExists(response, method.getAnnotations()); 
     putCacheControlIfExists(response, method.getResource().getAnnotations()); 
     return response; 
    } 

    private void putCacheControlIfExists(ContainerResponse response, Annotation[] annotations) 
    { 
     CacheControl annotation = findCacheControl(annotations); 
     if (annotation != null) 
      response.getHttpHeaders().put(CACHE_CONTROL, createCacheControlHeader(annotation)); 
    } 

    private CacheControl findCacheControl(Annotation[] annotations) 
    { 
     for (Annotation annotation : annotations) 
      if (annotation instanceof CacheControl) 
       return (CacheControl) annotation; 
     return null; 
    } 

    private List<Object> createCacheControlHeader(CacheControl annotation) 
    { 
     javax.ws.rs.core.CacheControl header = new javax.ws.rs.core.CacheControl(); 
     header.setMaxAge(annotation.maxAge()); 
     header.setMustRevalidate(annotation.mustRevalidate()); 
     header.setNoCache(annotation.noCache()); 
     header.setNoStore(annotation.noStore()); 
     header.setNoTransform(annotation.noTransform()); 
     header.setProxyRevalidate(annotation.proxyRevalidate()); 
     return Lists.<Object> newArrayList(Splitter.on(',').split(header.toString())); 
    } 

    @Override 
    public ContainerRequestFilter getRequestFilter() 
    { 
     return null; 
    } 

    @Override 
    public ContainerResponseFilter getResponseFilter() 
    { 
     return this; 
    } 
} 

cevap

4

Neden her uygulanabilir yöntem için filtrenin ayrı örneği yok etmek önemlidir? Çok sayıda eşzamanlı erişim olabilir, bu yüzden bunların ayrı örnekler olmasını istemiyorsanız, bunların değişebilir olması gerekirdi ve iş parçacığı karmaşasına girmeniz gerekirdi (söz konusu iş parçacığı için geçerli olan soyut yöntemi depolamak için)). Gerçekten istediğin şeyin bu olduğundan emin değilim. Her biri için ayrı bir nesneye sahip olmak o kadar da pahalı değil.

GÜNCELLEME: Ayrıca her yöntem için yeni bir örneğini oluşturmak istemiyoruz, not edin. Sadece onlara veya kaynaklarına ekli herhangi bir @CacheControl eki ile ilgili yöntemler için yapmak istiyorsunuz, değil mi? Ayrıca, ortak @ CacheControl değerleri için filtre örneklerini de paylaşabilirsiniz. Örneğin, bir yöntem başka bir yöntemle aynı önbellek denetimi ayarını kullanıyorsa, aynı filtreyi yeniden kullanmanız gerekir, eğer değilse, bu yöntemin filtresinin ayrı bir örneğini oluşturun. Başka bir deyişle, her yönteme göre bir filtre yerine tek bir önbellek denetim ayarı için bir filtreniz olabilir. Bu, yönteme gerçekten önem vermediğinden, ek açıklamaları dikkate alırsınız.

+0

Paylaşım örnekleri, gereken parçadır;) –

İlgili konular