Фабрика Джерси пытается дважды создать переменную @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).

Итак, чтобы это исправить, мне пришлось:

  1. Импортировать правильный AbstractBinder - org.glassfish.jersey.internal.inject.AbstractBinder(НЕ предыдущий от HK2 - org.glassfish.hk2.utilities.binding.AbstractBinder).

  2. Обновить фабрику для реализации Supplier<User> вместо Factory<User>,

После этого изменения все работает как и раньше, фабрика вызывается только один раз.

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