Фабрика Джерси пытается дважды создать переменную @Context
У меня проблема с Джерси 2.26 и Spring Boot 2.
Я добавил фабрику для инъекций @Context
переменная в методы, но она делает это дважды, сначала перед методом, а затем снова после метода:
@GET
@Path("/user-entitlements")
public Set<String> getUserEntitlements(@Context User user) {
return service.getUserEntitlements(user);
}
У меня есть фабрика, которая создает этих пользователей:
public class UserFactory implements Factory<User> {
private final User user;
@Inject
public UserFactory(HttpServletRequest request, RequestIdentityService requestIdentityService) {
String userName = requestIdentityService.getCurrentUser(request);
user = new User(userName);
}
@Override
public User provide() {
return user;
}
@Override
public void dispose(User instance) {
}
}
И в конфигурации джерси я регистрирую эту фабрику:
register(
new AbstractBinder() {
@Override
public void configure() {
bindFactory(UserFactory.class)
.to(User.class)
.in(RequestScoped.class);
}
}
);
Раньше он работал нормально, но после того, как я обновил приложение до джерси 2.26 и весенней загрузки 2, оно перестало работать и выдает исключение:
java.lang.IllegalStateException: Proxiable context org.glassfish.jersey.inject.hk2.RequestContext@3a94c454 findOrCreate returned a null for descriptor SystemDescriptor(
implementation=org.glassfish.jersey.inject.hk2.SupplierFactoryBridge
contracts={javax.servlet.http.HttpServletRequest}
scope=org.glassfish.jersey.process.internal.RequestScoped
qualifiers={}
descriptorType=PROVIDE_METHOD
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2@464366a8
proxiable=true
proxyForSameScope=false
analysisName=null
id=20
locatorId=0
identityHashCode=1360647282
reified=true) and handle ServiceHandle(SystemDescriptor(
implementation=com.rest.UserFactory
contracts={org.glassfish.hk2.api.Factory}
scope=org.glassfish.hk2.api.PerLookup
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2@33335025
proxiable=null
proxyForSameScope=null
analysisName=null
id=172
locatorId=0
identityHashCode=790201459
reified=true),1915928862)
Исключение появляется, потому что UserFactory вызывается дважды. Сначала он вызывается до вызова getUserEntitlements, чтобы внедрить пользователя. Но после возврата метода он вызывается снова (и на этот раз он получает реализацию HttpRequest, которая не разрешает некоторые операции).
Почему это можно назвать дважды? Как будто я бы попросил его усилить как запрос, так и ответ.
1 ответ
Проблема в том, что в Нью-Джерси они перешли от hk2 на уровень абстракции над ним и сделали код Java 8 осведомленным (потому что это реализация Java EE 8 - https://jersey.github.io/release-notes/2.26.html).
Итак, чтобы это исправить, мне пришлось:
Импортировать правильный
AbstractBinder
-org.glassfish.jersey.internal.inject.AbstractBinder
(НЕ предыдущий от HK2 -org.glassfish.hk2.utilities.binding.AbstractBinder
).Обновить фабрику для реализации
Supplier<User>
вместоFactory<User>
,
После этого изменения все работает как и раньше, фабрика вызывается только один раз.