2010-12-05 2 views
48

Я использовал Джерси в течение большей части года и только что наткнулся на проблему, на которую я не могу найти ответ: как вы перехватите (или зацепите) жизненный цикл запроса Джерси?Как перехватить запрос во время жизненного цикла Джерси?

В идеале, я мог бы выполнить некоторую пользовательскую фильтрацию/проверку/отклонение между временем, в течение которого контейнер принимает запрос из сети, и временем, когда вызываются методы моего обработчика. Бонусные точки, если есть простой способ фильтрации перехватчиков по подпутью (например, есть один перехватчик для чего-либо под /, другой для чего-либо под/user/и т. Д.).

Спасибо!

Редактировать: Чтобы быть немного понятнее, общая идея здесь - написать код, который будет запущен для многих вызовов API без необходимости явного вызова этого кода из каждого метода обработчика. Это уменьшило бы дополнительный код и устранило бы необходимость передавать контексты запросов.

+0

Какая фильтрация, проверка, отклонение вы хотите? Например, вы можете создать свой собственный MessageBodyWriter/Reader для проверки валидации. Или вы можете установить @Context в конструкторе для пользовательского разбора HTTP-заголовков или разбора URI. – Marc 2010-12-05 09:53:34

+0

Большинство приложений этой функции будут связаны с безопасностью. Например, мое (не-Джерси) веб-приложение будет генерировать одноразовые nonces для определенных вызовов AJAX (все под тем же путем) до Джерси. Перехватчик будет отвечать за проверку действительности этого nonce. – cww 2010-12-05 10:04:51

+0

@Marc вы можете рассказать немного больше о «Или вы можете установить @ Контекст в конструкторе для пользовательского анализа заголовков HTTP или партирования URI», пожалуйста? – Mat 2012-12-20 15:42:55

ответ

50

я нашел ответ?.

Сначала создайте класс, который реализует ContainerRequestFilter. Интерфейс определяет следующий метод, в котором происходит фильтрация. Объект ContainerRequest содержит информацию о текущем запросе.

public ContainerRequest filter(ContainerRequest req); 

После этого, включают в себя следующие XML в конфигурации сервлета в web.xml

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

Источники:

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

-1

Вы посмотрели на класс Джерси ClientFilter?

В настоящее время мы используем это для перехвата и выполнения API-интерфейсов и т. Д. Там встроены фильтры регистрации, поэтому вы можете посмотреть на код, чтобы получить представление о том, что писать.

Подпись:

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

Таким образом, вы можете начать делать такие вещи, как:

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

Похоже, что это работает только на стороне клиента. Вы знаете, есть ли подобный механизм фильтрации для сервера? – cww 2010-12-05 11:59:43

0

Для серверной части мы используем Джерси конкретный класс, чтобы сделать что-то вроде этого: ContainerResponseFilter

Подпись:

public ContainerResponse filter(ContainerRequest request, ContainerResponse response) 

, то вы можете сделать звонки, как:

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

Может ли это иметь некоторую помощь ..

8

Эта нить немного старый, но У меня была подгонка времени, перехватывающая как до, так и после запрос.После длительного поиска в Интернете, я, наконец, понял это:

<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> 

, а затем этот класс:

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()); 
     //... 
    } 

Это перехватывает запрос на начало и конец, так что вы можете поместить в таймере или что-то еще.

Это работает для Джерси 1.17. Не уверен насчет 2.x.

Смежные вопросы