2010-12-05 14 views
48

He usado Jersey durante la mayor parte de un año y acabo de tropezar con un problema para el cual no puedo encontrar la respuesta: ¿cómo se intercepta (o engancha) el ciclo de vida de la solicitud de Jersey?¿Cómo se intercepta una solicitud durante el ciclo de vida de Jersey?

Idealmente, podría realizar algún filtrado/validación/rechazo personalizado entre el momento en que el contenedor acepta la solicitud de la red y el momento en que se llaman a mis métodos de manejo. Puntos de bonificación si hay una manera fácil de filtrar los interceptores por subruta (por ejemplo, tener un interceptor para cualquier cosa debajo de /, otra para cualquier cosa debajo/usuario /, etc.).

Gracias!

Editar: Para ser un poco más claro, la idea general aquí es poder escribir algún código que se ejecutará para muchas llamadas a la API sin tener que llamar explícitamente a ese código desde cada método del controlador. Esto reduciría el código adicional y eliminaría la necesidad de pasar contextos de solicitud.

+0

¿Qué tipo de filtrado, validación, rechazo quieres? Por ejemplo, puede crear su propio MessageBodyWriter/Reader para manejar la validación. O puede configurar @Context en el constructor para el análisis de encabezado HTTP personalizado o el análisis URI. – Marc

+0

La mayoría de las aplicaciones de esta función estarían relacionadas con la seguridad. Por ejemplo, mi aplicación web (que no sea de Jersey) generará nonces de uso único para ciertas llamadas AJAX (todas bajo la misma ruta) a Jersey. El interceptor sería responsable de verificar la validez de este nonce. – cww

+0

@Marc ¿Puedes contarnos un poco más sobre "O puedes configurar el @ Contexto en el constructor para analizar el encabezado HTTP personalizado o analizar el URI", por favor? – Mat

Respuesta

50

que he encontrado la respuesta?.

Primero, crea una clase que implemente ContainerRequestFilter. La interfaz especifica el siguiente método, en el que se realiza el filtrado. El objeto ContainerRequest contiene información sobre la solicitud actual.

public ContainerRequest filter(ContainerRequest req); 

Después de eso, se incluyen los siguientes XML en la configuración servlet en web.xml

<init-param> 
    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name> 
    <param-value>path.to.filtering.class</param-value> 
</init-param> 

Fuentes:

http://jersey.576304.n2.nabble.com/ContainerRequestFilter-and-Resources-td4419975.html http://markmail.org/message/p7yxygz4wpakqno5

+5

Gracias por agregar su solución, es útil para el resto de nosotros – tddmonkey

+1

¿Hay alguna anotación para esto? – Shekhar

+0

¿Cómo rechazar la solicitud con esto? –

-1

¿Has mirado la clase Jersey ClientFilter?

Actualmente estamos usando esto para interceptar y realizar API versioing, etc. Hay filtros de registro integrados, por lo que puede ver el código para que se den una idea de qué escribir.

La firma es:

public ClientResponse handle(final ClientRequest cr) throws ClientHandlerException... 

para que pueda empezar haciendo cosas como:

.... 
cr.getHeaders() 
.... 
return getNext().handle(cr); 
+1

Parece que esto funciona únicamente en el lado del cliente. ¿Sabes si hay un mecanismo de filtrado similar para el servidor? – cww

0

Por parte del servidor que utilizamos una clase específica Jersey para hacer algo como esto: ContainerResponseFilter

La firma es:

public ContainerResponse filter(ContainerRequest request, ContainerResponse response) 

entonces usted puede hacer llamadas como:

Object entity = response.getEntity(); 
    ... your logic here ... 
return response; 

¿Puede ser de alguna ayuda ..

8

Este hilo es un poco viejo, pero Estaba teniendo un ataque de un tiempo interceptando ambos antes y después de la solicitud.Después de una larga búsqueda en la web, por fin cuenta de esto:

<init-param> 
    <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name> 
    <param-value>blah.LoggingFilter</param-value> 
</init-param> 
<init-param> 
    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name> 
    <param-value>blah.LoggingFilter</param-value> 
</init-param> 

y luego esta clase:

public class LoggingFilter extends LoggingFilter implements ContainerRequestFilter { 

    private static final ThreadLocal<Long> startTime = new ThreadLocal<Long>(); 
    public static boolean verboseLogging = false; 

    @Override 
    public ContainerRequest filter(ContainerRequest arg0) { 
     startTime.set(System.currentTimeMillis()); 
     return arg0; 
    } 

    @Override 
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { 
     System.out.println(System.currentTimeMillis() - startTime.get().longValue()); 
     StringBuilder sb = new StringBuilder(); 
     sb.append("User:").append((request.getUserPrincipal() == null ? "unknown" : request.getUserPrincipal().getName())); 
     sb.append(" - Path:").append(request.getRequestUri().getPath()); 
     //... 
    } 

Este intercepta la solicitud al principio y al final lo que puede poner en un temporizador o lo que sea.

Esto funciona para Jersey 1.17. No estoy seguro acerca de 2.x.

+0

Necesitamos unset thread local en el filtro de respuesta –

+0

Creo que tomcat puede reutilizar hilos. Para estar seguro, configúralo en cero ... – markthegrea

Cuestiones relacionadas