Могу ли я создать объект в области запроса и получить к нему доступ из любого места и избежать его передачи в качестве параметра в 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.