Могу ли я создать объект в области запроса и получить к нему доступ из любого места и избежать его передачи в качестве параметра в JAX-RS?

Скажем, у меня есть веб-служба / ресурс REST, который вызывается с некоторыми параметрами заголовка HTTP. Метод resource создает сложный объект данных (в настоящее время POJO) и в конечном итоге возвращает его клиенту (через Gson как JSON, но это не имеет значения).

Итак, у меня есть эта иерархия вызовов:

@Path(foo) ProjectResource @GET getProject()
-> new Project()
-> new List<Participant> which contains lots of new Participant()s
-> new Affiliation()

Если я хочу Affiliation Например, для заполнения объекта на английском или немецком языке, в зависимости от параметра заголовка, я должен передать его в качестве параметра по цепочке. Я хочу избежать необходимости делать это. Может быть, это просто принципиально невозможно, но это так неправильно. Все эти объекты живут только внутри запроса, поэтому не было бы удобно иметь доступ к информации, связанной с запросом, из любого места?

Я надеялся, что смогу, например, определить CDI @RequestScoped объект, который инициализируется сам (или заполняется каким-либо WebFilter) и который я могу затем внедрить туда, где он может мне понадобиться.

Но очевидно, что это не работает внутри POJO, и у меня также были проблемы с захватом заголовков внутри объекта в области запроса.

Я прочитал много SO вопросов / ответов о EJB и JAX-RS Context и CDI, но не могу обойти это.

Я ожидаю слишком многого? Действительно ли передача по параметру является предпочтительным вариантом?

1 ответ

Если я понимаю, что вам нужно, вы можете попробовать следующее (только что написал это решение из головы, но оно должно работать):

Определение класса для хранения нужных вам данных

Определите класс с пометкой @RequestScoped который будет хранить нужные вам данные:

@RequestScoped
public class RequestMetadata {

    private Locale language;

    // Default constructor, getters and setters ommited
}

Убедитесь, что вы используете @RequestScoped аннотация от javax.enterprise.context пакет.

Создание фильтра запросов

Создать ContainerRequestFilter заселить RequestMetadata:

@Provider
@PreMatching
public class RequestMetadataFilter implements ContainerRequestFilter {

    @Inject
    private RequestMetadata requestMetadata;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        requestMetadata.setLanguage(requestContext.getLanguage());
    }
}

Выполнение инъекции

И тогда вы, наконец, можете выполнить инъекцию RequestMetadata с помощью @Inject:

@Stateless
public class Foo {

    @Inject
    private RequestMetadata requestMetadata;

    ...
}

Пожалуйста, имейте в виду, что где-то слишком широк: инъекция будет работать в bean-компоненты, управляемые контейнером, такие как сервлеты, классы JAX-RS, EJB и CDI-компоненты.

Вы не сможете выполнять инъекции в бины, созданные вами, ни в объекты JPA.

Другие вопросы по тегам