#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
, и теперь это работает… Единственное, о чем я могу думать, это о том, что теперь он использует другой метод инициализации.