jax-rs делятся информацией между ContainerRequestFilter и ReaderInterceptor - PullRequest
0 голосов
/ 25 октября 2018

Я использую Jax-rs, и я делаю некоторую логику в Filters, а затем я хотел бы поделиться информацией между ContainerRequestFilter (Фильтр) и ReaderInterceptor (Перехватчик).

Я вижу, что между фильтрами и перехватчиками можно через set/getProperties, но между фильтрами и перехватчиками невозможно.

Есть идеи, есть ли какой-нибудь другой механизм ?.

С уважением.

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Таким образом, любой более простой способ, чем , используя отдельный сервис для этого , - просто ввести ContainerRequestContext в ReaderInterceptor.Нам нужно ввести его как javax.inject.Provider, чтобы мы могли его лениво извлечь.Если мы этого не сделаем, у нас возникнут проблемы с областями видимости, поскольку перехватчик по своей сути является одноэлементным, а контекст запроса - областью действия запроса (то есть для каждого запроса создается новый).

public static class MyInterceptor implements ReaderInterceptor {
    private final javax.inject.Provider<ContainerRequestContext> requestProvider;

    @Inject
    public MyInterceptor(javax.inject.Provider<ContainerRequestContext> requestProvider) {
        this.requestProvider = requestProvider;
    }

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) throws IOException, WebApplicationException {
        ContainerRequestContext request = requestProvider.get();
        String prop = (String) request.getProperty("SomeProp");
    }
}

С javax.inject.Provider мы получаем реальную услугу, звоня get().Поскольку мы используем Provider, служба будет извлечена из контекста области запроса, то есть экземпляр будет привязан к запросу.


1.См. Запрос дополнительной инъекции в синглтон с Джерси для получения дополнительной информации.

0 голосов
/ 25 октября 2018

Вы можете использовать сервис с областью запроса, который вы внедрили как в фильтр, так и в перехватчик.Например,

public interface RequestScopedService {
    void setSomething(Object something);
    Object getSomething();
}

public class RequestScopedServiceImpl implements RequestScopedService {
    @Override
    public void setSomething(Object something) {}

    @Override
    public Object getSomething() {}
}

Лучше всего использовать интерфейсы, поэтому я сделал это здесь.Чтобы настроить его, вы регистрируете AbstractBinder с помощью ResourceConfig 1 .

public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(new AbstractBinder() {
            @Override
            public void configure() {
                bind(RequestScopedServiceImpl.class)
                        .to(RequestScopedService.class)
                        .proxy(true)
                        .proxyForSameScope(false)
                        .in(RequestScoped.class);
            }
        });
    }
}

Теперь вы можете ввести его как в фильтр, так и в перехватчик.

public class MyFilter implements ContainerRequestFilter {
    private final RequestScopedService service;

    @Inject
    public MyFilter(RequestScopedService service) {
        this.service = service;
    }
}

public class MyInterceptor implements ReaderInterceptor {
    private final RequestScopedService service;

    @Inject
    public MyInterceptor(RequestScopedService service) {
        this.service = service;
    }
}

Мы используем метод proxy() для его настройки, потому что сервис является сервисом с ограниченным объемом запросов (т. Е. Новый создается для каждого запроса), а перехватчик фильтра и записи является одиночными.Таким образом, нам нужен прокси-сервер, который перенаправляет звонки на реальный сервис под капотом 2 .


1.Если вы не используете ResourceConfig для своей конфигурации (возможно, вы используете web.xml), см. Оба моих ответа в "Внедрение зависимостей с Джерси 2.0 и Что такое класс ResourceConfig вДжерси 2? .

2. Вы можете узнать больше об этом в этой статье

...