这是一个关于更好地将嵌入jetty的代码与连接servlet的代码分离的问题。
我正在尝试调整这个示例代码,以便获得一个可运行的war,即一个可以放入现有Jetty容器中的war文件,或者使用类似java -jar webapp-runnable.war
的命令独立运行。示例代码属于这两篇博客文章:No.1,No.2。
我遵循了GuiceServlet手册并创建了web.xml
和GuiceServletContextListener
(见下文),但它们似乎并没有让我在mvn jetty:run
方面走得很远;当我尝试运行mvn jetty:run
时,我得到以下错误:
[main] DEBUG org.eclipse.jetty.util.log - Logging to Logger[org.eclipse.jetty.util.log] via org.eclipse.jetty.util.log.Slf4jLog
WARN:oejw.WebAppContext:main: Failed startup of context o.e.j.m.p.JettyWebAppContext@3cceafcb{/,file:/[...]/src/main/webapp/,STARTING}{file:/[...]/src/main/webapp/}
com.google.inject.ConfigurationException: Guice configuration errors:||1) Explicit bindings are required and com.google.inject.servlet.InternalServletModule$BackwardsCompatibleServletContextProvider is not explicitly bound.| while locating com.google.inject.servlet.InternalServletModule$BackwardsCompatibleServletContextProvider||1 error
at [stack strace clipped]
这是我的代码如前所述,我从github上的这个repo开始。
1)我从com.teamlazerbeez.http.HttpServerMain
中提取了AbstractModule类型的匿名内部类,并将其放入一个新的类com.teamlazerbeez.http.HttpServerModule
中。这个类现在在HttpServerMain
(l36)中创建Guice Injector时被实例化。
2)我的web.xml
:
<?xml version="1.0" ?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
metadata-complete="false"
version="3.0">
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.teamlazerbeez.http.GuiceServletConfig</listener-class>
</listener>
</web-app>
3)我的com.teamlazerbeez.http.GuiceServletConfig
:
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
//I know this code not come close to doing what I want, but I just don't know where to start
return Guice.createInjector(new HttpServerModule());
}
}
我的问题:如何重构HttpServerMain
main
方法和HttpServerModule
,使它们描述的设置过程可用于我的GuiceServletConfig
?GuiceServletConfig
必须是什么样子才能工作?
我从来没有像jar那样使用过war,所以我总是选择两种解决方案中的一种。然而,当使用war时,设置一个在IDE中工作的嵌入式Jetty服务器并不困难。为此,您可以使用WebAppContext
来使用web.xml
进行设置。有关示例,请参阅本文档。从那里开始,一切都应该按照吉策遗址的主张进行。
然而,这不会创建一个可运行的war(如java -jar yourapp.war
),因为jar有不同的内部布局。但是,如果您愿意,您可以使用jetty runner使用java -jar jetty-runner.jar yourapp.war
来修复此问题。
我接受了@Alex的建议,忘记了创建一个独立的可运行的war
,而是专注于创建一个war
,它在guide Servlet模块中完成大部分布线。
为此,我更改了HttpServerModule
以扩展ServletModule
(而不是AbstractModule
),并将大部分HttpServerMain.main()
逻辑放在其configureServlets()
方法中:
public class HttpServerModule extends ServletModule {
@Override
protected void configureServlets() {
MetricRegistry metricRegistry = new MetricRegistry();
bind(MetricRegistry.class).toInstance(metricRegistry);
install(new SandwichModule());
install(new JerseyMetricsModule());
JmxReporter reporter = JmxReporter.forRegistry(metricRegistry).build();
reporter.start();
}
}
您会注意到一些HttpServerMain.main()
逻辑现在不再出现在java代码中。这是因为web.xml
现在负责处理这些事情。
我的web.xml
和GuiceServletConfig
保持不变,现在我可以使用mvn jetty:run command
运行它了。HttpServerMain现在可以被删除,因为它不再做任何有用的事情。