Search code examples
websocketweb.xmlspring-4welcome-file

Spring 4 DispatcherServlet mapping with websockets


I am working to add Spring 4's new websocket abilities to an existing enterprise Spring web application.

Most of the examples out there for this are based on using Spring's annotation configuration and more importantly Spring Boot. My application uses neither and there is simply no time/interest in converting it to do so.

With a bunch of research I have gotten around most of the problems with configuring our application slightly differently than the examples (XML configuration and deployment to a tomcat server in Eclipse).

The roadblock I am facing right now is the DispatcherServlet's mapping. In order to get the websockets to work I had to move from something that looked like this:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.htm</url-pattern>
    <url-pattern>*.json</url-pattern>
    <url-pattern>*.tpl</url-pattern>
    <!-- REST web services location -->
    <url-pattern>/api/*</url-pattern>
    <url-pattern>/gadget/*</url-pattern>
    <url-pattern>/rr/*</url-pattern>
    <url-pattern>/public/*</url-pattern>
</servlet-mapping>

To something that looked like this:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>/WEB-INF/mvc-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

I simply couldn't find any other way to get the DispatcherServlet to pick up all the websocket communication. That is mostly fine though. I added the following to my context XML to still be able to serve static resources:

<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/**/favicon.ico" location="/favicon.ico" />

Now for the real issue, using the root mapping "/" it seems that the welcome file list you can provide in the web.xml is being completely ignored. I am using the following list at the bottom of my web.xml:

<welcome-file-list>
    <welcome-file>index.htm</welcome-file>
</welcome-file-list>

There are dozens of URL paths in our application that rely on an untyped "index.htm" being loaded from an empty URL path, example https://somesite.com/member/account/

How can I either do a specific mapping to the DispatcherServlet that picks up my websocket communication OR get the welcome file list to work again with just a "/" mapping?


Solution

  • I found a solution that seems to work well. I was thinking of my old servlet mappings and the new "/" mapping as being mutually exclusive but that is not the case. I simply added the "/" mapping to my existing ones and now the DispatcherServlet seems to be serving JSP, JSON and websocket requests no problem, including welcome file URL paths.