春季启动 DispatcherServlet
Posted
技术标签:
【中文标题】春季启动 DispatcherServlet【英文标题】:Spring boot DispatchServlet 【发布时间】:2015-04-18 12:06:41 【问题描述】:我有一个 spring boot 项目(带有嵌入式 jetty9 的可执行 jar)。
我应该注册 2 个不同的 DispatcherServlet。我是这样做的:
@Bean
public ServletRegistrationBean dispatcherServlet()
DispatcherServlet servlet = new DispatcherServlet();
ServletRegistrationBean sr = new ServletRegistrationBean(servlet, "/graniteamf/*");
return sr;
@Bean
@Order(2)
public ServletRegistrationBean customDispatcherServlet()
DispatcherServlet servlet = new DispatcherServlet();
ServletRegistrationBean sr = new ServletRegistrationBean(servlet, "/client/*");
return sr;
不幸的是,当我尝试启动应用程序时,我遇到了这个异常:
17/02/2015 18:24:04 INFO ApacheAsyncTransport:54 - Starting Apache HttpAsyncClient transport...
17/02/2015 18:24:04 INFO ApacheAsyncTransport:54 - Apache HttpAsyncClient transport started.
17/02/2015 18:24:04 DEBUG Application:173 - Inizializzazione identity
17/02/2015 18:24:04 ERROR DispatcherServlet:497 - Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:452)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:629)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:677)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:548)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:612)
at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:395)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:871)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedWebAppContext$JettyEmbeddedServletHandler.deferredInitialize(JettyEmbeddedWebAppContext.java:46)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedWebAppContext.deferredInitialize(JettyEmbeddedWebAppContext.java:36)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.handleDeferredInitialize(JettyEmbeddedServletContainer.java:162)
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.start(JettyEmbeddedServletContainer.java:109)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:287)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at it.pianetatecno.gsmgateway.Application.main(Application.java:61)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)
... 30 more
17/02/2015 18:24:05 ERROR SpringApplication:339 - Application startup failed
org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Jetty servlet container
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.start(JettyEmbeddedServletContainer.java:119)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:287)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at it.pianetatecno.gsmgateway.Application.main(Application.java:61)
我有两个问题:
-
dispatcherServlet 的 xml 文件是强制性的吗?
Spring 希望在哪个文件夹中找到这个文件?我尝试将其放入资源/WEB-INF,但它不起作用。
编辑的问题
这是我在 Spring Boot 中的主要方法:
@SpringBootApplication
公共类应用程序 私有静态 Logger log = Logger.getLogger(Application.class);
private static ApplicationContext context;
public static void main(String[] args)
SpringApplication app = new SpringApplication(Application.class);
app.setShowBanner(false);
context = app.run(args);
app.setShowBanner(false);
谢谢
【问题讨论】:
为什么您需要多个 servlet? Front Controller 的全部意义在于您通常只需要一个。 假设我只使用了一个 DispatcherServlet。在这种情况下,我也有例外。 Spring 尝试加载 xml,但我没有找到使用 Spring 引导配置 DispatcherServlet 的最佳实践。谢谢 你就是不这样做。完全没有。包含 starter-web 和 Spring Boot 会自动执行所有操作。 【参考方案1】:您不需要 XML,但您需要在 servlet 上设置 ApplicationContext
。如果它是 @Bean
(就像在 Spring Boot 中的 DispatcherServletAutoConfiguration
中一样),Spring 会为您执行此操作,或者我想您可以手动执行此操作。
【讨论】:
我在原始问题上添加了我的主要方法。不太清楚如何将此上下文提供给 DispatcherServlet。 您可以将应用程序上下文作为方法参数注入任何@Bean
方法中,也可以将@Autowired
作为字段或设置器注入。这是标准的 Spring 东西(不是 Boot)。或者你可以按照我的建议将 servlet 制作成 bean。
@Dave 这是否总是相同的ApplicationContext
实例?引导是否有单独的(Web)ApplicationContext
实例,一个用于DispatcherServlet
,一个用于ContextLoaderListener
,一个用于等?
Spring Boot 通常适用于单个应用程序上下文,但如果您需要它们,没有什么能阻止您创建其他上下文。以上是关于春季启动 DispatcherServlet的主要内容,如果未能解决你的问题,请参考以下文章