RestEasy / Guice: не удается внедрить объект в ContainerRequestFilter

#java #jax-rs #guice #resteasy

#java #jax-rs #интерфейс #resteasy

Вопрос:

Мне нужно ContainerRequestFilter обработать авторизацию запроса, и я хочу внедрить реализацию моего AuthService интерфейса в его конструктор (я использую Guice для DI). Однако я не смог понять, как заставить внедрение зависимостей работать.

Мой класс фильтра выглядит следующим образом:

 public class UserRoleFilter implements ContainerRequestFilter {

protected AuthService authService;

@Context
private ResourceInfo resourceInfo;

@Inject
public UserRoleFilter(AuthService authService) {
    this.authService = authService;
}

@Override
public void filter(ContainerRequestContext requestContext) {
    this.authService.doSomething(...);
}
  

Однако, когда я запускаю программу, я получаю NullPointerException from org.jboss.resteasy.core.ConstructorInjectorImpl.<init> .

Запуск моего приложения — это:

 public static void main(String[] args) throws Exception {       
    Injector injector = Guice.createInjector(new RestApplicationModule(args));
    initServer(injector).join();
}

public static Server initServer(Injector injector) throws Exception {
    Server server = new Server(SERVER_PORT);
    ServletContextHandler servletHandler = new ServletContextHandler();
    servletHandler.setInitParameter("resteasy.role.based.security", "true");
    servletHandler.setInitParameter("resteasy.providers", UserRoleFilter.class.getName());
    servletHandler.addEventListener(injector.getInstance(GuiceResteasyBootstrapServletContextListener.class));

    servletHandler.addServlet(HttpServletDispatcher.class, "/*");

    // Create the SessionHandler (wrapper) to handle the sessions
    SessionManager manager = new HashSessionManager();
    SessionHandler sessions = new SessionHandler(manager);
    servletHandler.setSessionHandler(sessions);

    server.setHandler(servletHandler);
    server.start();
    return server;
}

private static class RestApplicationModule extends RequestScopeModule {       

    public RestApplicationModule(String[] args) {
    }

    @Override
    protected void configure() {
        super.configure();                     
        bind(AuthService.class).to(AuthServiceImpl.class);
        bind(UserRoleFilter.class);
        // Bind JAX-RS Controller classes
    }
}
  

Разбираясь в коде инициализации RestEasy, похоже, мне придется добавить @Context атрибут к authService параметру в моем конструкторе, чтобы RestEasy его принял. Это передает прокси-объект и позволяет серверу запуститься, но как только фильтр пытается получить доступ к AuthService, я получаю:
RESTEASY003880: Unable to find contextual data of type: com.genghiszahn.authFilterTest.AuthService

Комментарии:

1. После долгих размышлений вслепую я решил это, хотя и не уверен, почему это сработало. Я удалил setInitParameter строки из initServer и добавил атрибут @Provider в UserRoleFilter , и теперь это работает… Единственное, о чем я могу думать, это о том, что теперь он использует другой метод инициализации.