如何在一个 Spring 应用程序的 web.xml 中注册多个 servlet

Posted

技术标签:

【中文标题】如何在一个 Spring 应用程序的 web.xml 中注册多个 servlet【英文标题】:How to register multiple servlets in web.xml in one Spring application 【发布时间】:2010-12-24 07:39:17 【问题描述】:

我想在我的 Spring web.xml 中定义两个 servlet——一个用于应用程序 html/jsp 页面,一个用于将由外部应用程序调用的 Web 服务。这是web.xml:

<servlet>
  <servlet-name>myservlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>myservlet</servlet-name>
  <url-pattern>*.htm</url-pattern>
</servlet-mapping>

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>WEB-INF/user-service-servlet.xml</param-value>
</context-param>

<servlet>
  <servlet-name>user-webservice</servlet-name>
  <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>user-webservice</servlet-name>
  <url-pattern>/UserService/*</url-pattern>
</servlet-mapping>

如果我让 myservlet 单独使用文件中的 DispatcherServlet,它可以正常工作。如果我有带有上下文参数的用户 web 服务,它的配置文件 (user-service-servlet.xml),它工作正常。但是,如果我在文件中同时包含两者,则 myservlet 将无法工作,因为 myservlet-servlet.xml 文件不会自动加载。如果我删除上下文参数,那么 myservlet 可以工作,但用户 Web 服务不起作用,因为它的配置文件 (user-service-servlet.xml) 没有加载。

如何定义两个 servlet 并加载它们的两个配置文件?

【问题讨论】:

【参考方案1】:

正如 cxf-user 邮件列表上的 this thread 中所述,您可以将全部内容加载到根上下文中,而不是让 CXFServlet 从 user-webservice-servlet.xml 加载它自己的 spring 上下文。将现有的 user-webservice-servlet.xml 重命名为其他名称(例如 user-webservice-beans.xml),然后将 contextConfigLocation 参数更改为:

<servlet>
  <servlet-name>myservlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>myservlet</servlet-name>
  <url-pattern>*.htm</url-pattern>
</servlet-mapping>

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    /WEB-INF/applicationContext.xml
    /WEB-INF/user-webservice-beans.xml
  </param-value>
</context-param>

<servlet>
  <servlet-name>user-webservice</servlet-name>
  <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>user-webservice</servlet-name>
  <url-pattern>/UserService/*</url-pattern>
</servlet-mapping>

【讨论】:

如果使用单独的数据库和其他设置,两个 servlet 的上下文如何可以在根上下文中?在一个文件中如何区分它们?【参考方案2】:

使用类似这样的配置:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
  <servlet-name>myservlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet>
  <servlet-name>user-webservice</servlet-name>
  <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
</servlet>

然后你需要三个文件:

applicationContext.xml; myservlet-servlet.xml;和 user-webservice-servlet.xml。

*-servlet.xml 文件会自动使用,每个文件都会为该 servlet 创建一个应用程序上下文。

来自 Spring 文档,13.2. The DispatcherServlet:

框架将在初始化时 DispatcherServlet寻找 名为 [servlet-name]-servlet.xml 的文件 在您网站的WEB-INF 目录中 应用程序并创建 bean 在那里定义(覆盖 定义的任何 bean 的定义 在全局范围内同名)。

【讨论】:

这无济于事 - 我的应用程序中有这些文件,但是当我转到 localhost:8080/MyApp/index.jsp 时,它会显示页面,但是当我转到 localhost:8080/MyApp 时(没有斜杠) ,它会打开用户 Web 服务,但单击 WSDL 链接会显示“未找到服务”消息。也许我的问题不是没有加载配置文件,而是映射到 Web 服务不正确。【参考方案3】:

我知道这有点旧,但简而言之,答案是 两次出现都给出了相同的 id,即两次为 1。这可能会混淆加载顺序。

【讨论】:

以上是关于如何在一个 Spring 应用程序的 web.xml 中注册多个 servlet的主要内容,如果未能解决你的问题,请参考以下文章

Druid数据源SQL数据库与Spring监控

decorators.xml的用法

javaweb面试题

java笔试题:如何修改session的存活时间

web项目启动流程探索

jsp 使用application.getInitParameter来获取web.xml中配置参数