Бегущая война с пристани + хитрость
Это вопрос о том, как лучше отделить код для встраивания Jetty от кода для подключения сервлетов.
Я пытаюсь адаптировать этот пример кода таким образом, чтобы я получал работоспособную войну, то есть файл войны, который я могу перетащить в существующий контейнер Jetty или запустить автономно с помощью такой команды, как java -jar webapp-runnable.war
, Пример кода принадлежит этим двум постам в блоге: № 1, № 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.
1) Я извлек анонимный внутренний класс типа AbstractModule из com.teamlazerbeez.http.HttpServerMain
и положить его в новый классcom.teamlazerbeez.http.HttpServerModule
, Этот класс теперь создается при создании Guice Injector вHttpServerMain
(1336).
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
похоже, чтобы это работало?
2 ответа
У меня никогда не было войны, работающей как баночка, поэтому я всегда выбираю одно из двух решений. Однако при использовании войны нетрудно настроить встроенный сервер Jetty, который работает в вашей IDE. Для этого вы можете использовать WebAppContext
установить его с помощью web.xml
, Смотрите эту документацию для примера. Оттуда все должно работать так, как на сайте Guice.
Тем не менее, это не создаст управляемую войну (как java -jar yourapp.war
) потому что банки имеют разную внутреннюю планировку. Однако, если вы хотите, вы можете использовать причал, чтобы исправить это с помощью java -jar jetty-runner.jar yourapp.war
,
Я воспользовался советом Alex и забыл о создании автономного запуска war
и вместо этого сосредоточился на создании просто war
это делает большую часть проводки в форме ServletModule.
Для этого я поменял 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 теперь можно удалить, так как он больше не делает ничего полезного.