Как я могу получить аннотации ресурсов в Jersey ContainerResponseFilter

Jersey предлагает два класса для взаимодействия с аннотациями на ресурсах:

  • ResourceFilterFactory, один класс может наследовать его, чтобы он срабатывал один раз при запуске приложения
  • ContainerRequestFilter, ContainerResponseFilter, несколько классов могут наследовать их для запуска при каждом запросе/ответе

ResourceFilterFactory определяет create метод (для реализации), который принимает AbstractMethod, который дает доступ к методам и аннотациям классов.

ContainerRequestFilter и ContainerResponseFilter определяют filter метод (для реализации), который принимает запрос/ответ, но они дают доступ только к аннотации вызванного метода, а не класса.

Я пытаюсь реализовать аннотацию CacheControl, определяющую заголовки кэша HTTP, следующим образом.

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

Моя проблема в том, что я не хочу создавать новый CacheControlFilter для каждого метода REST, определенного в моем приложении.

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

    private boolean isAnnotationPresent(AbstractMethod method, Class clazz)
    {
        return method.isAnnotationPresent(clazz) || method.getResource().isAnnotationPresent(clazz);
    }
}

Есть ли способ получить доступ к AbstractMethod без создания CacheContronlFilter для каждого метода REST?

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 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. newArrayList(Splitter.on(',').split(header.toString()));
    }

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

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

10
задан yves amsellem 29 November 2011 в 17:43
поделиться