我最近切换到两阶段注入(inject),这在我的 servlet 绑定(bind)中造成了错误。我目前正在两种错误模式之间切换,不确定哪个方向最好。
我遇到的第一个错误是:
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
我的 servlet 模块如下所示:
public class MyServletModule extends JerseyServletModule {
@Override
protected void configureServlets() {
bind(MyServlet.class).asEagerSingleton();
serve("/*").with(GuiceContainer.class);
}
}
我能够通过显式提供 com.sun.jersey.config.property.packages 参数来消除此错误。
public class MyServletModule extends JerseyServletModule {
@Override
protected void configureServlets() {
bind(MyServlet.class).asEagerSingleton();
Map<String,String> parameters = new HashMap<String, String>();
parameters.put(PackagesResourceConfig.PROPERTY_PACKAGES, MyServlet.class.getPackage().getName());
serve("/*").with(GuiceContainer.class, parameters);
}
}
但是当我这样做时,Guice 会尝试进行即时绑定(bind),这不符合我的 servlet 构造函数上的 @Inject。
com.google.inject.ConfigurationException: Guice configuration errors:
1) Unable to create binding for MyServlet. It was already configured on one or more child injectors or private modules bound at MyServletModule.configureServlets(MyServletModule.java:44) If it was in a PrivateModule, did you forget to expose the binding? while locating MyServlet
1 error at com.google.inject.internal.InjectorImpl.getBinding(InjectorImpl.java:150)
我的 servlet 有一个 @Inject 构造函数,它的参数不能及时绑定(bind)。调试 InjectorImpl 后,我相信这就是我使用 PROPERTY_PACKAGES 时失败的原因。
我只是不确定使用 PROPERTY_PACKAGES 是否正确并且我需要修复一些绑定(bind)?或者,如果这是错误的方向,我需要以不同的方式修复原始的 ResourceConfig 错误。
感谢帮助或插入正确的方向。
最佳答案
通过单独绑定(bind)资源,我无需使用绑定(bind)参数(无需显式提供 com.sun.jersey.config.property.packages 参数)即可将 Jersey 资源绑定(bind)到 Guice
public class BindJerseyResources extends ServletModule {
@Override
protected void configureServlets() {
// excplictly bind GuiceContainer before binding Jersey resources
// otherwise resource won't be available for GuiceContainer
// when using two-phased injection
bind(GuiceContainer.class);
// bind Jersey resources
PackagesResourceConfig resourceConfig = new PackagesResourceConfig("jersey.resources.package");
for (Class<?> resource : resourceConfig.getClasses()) {
bind(resource);
}
// Serve resources with Jerseys GuiceContainer
serve("/*").with(GuiceContainer.class);
}
}
资源如下
@Path("/")
@RequestScoped
public class Resource {
private Storage storage;
@Inject
public Resource(Storage storage) {
this.storage = storage;
}
@GET
@Path("get/{name}")
@Produces(MediaType.TEXT_PLAIN)
public String getGuid(@PathParam("name") String name) {
return storage.get(name);
}
}
也许这可以帮助您避免后者有问题的绑定(bind)。
更新了使用两阶段注入(inject)的答案。
关于java - Guice - Jersey - Servlet 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18972198/