3

I'm learning sockets in java Tomcat. I have running tutorial example like:

@ServerEndpoint("/echo") 
public class EchoServer {
    @OnOpen
    public void onOpen(Session session){
       System.out.println(session.getId() + " has opened a connection"); 
    }

    @OnMessage
    public void onMessage(String message, Session session){
        System.out.println("Message from " + session.getId() + ": " + message);
    }

    @OnClose
    public void onClose(Session session){
        System.out.println("Session " + session.getId() + " has ended");
    }
}

and a proper html file connecting to this socket via javascript. My problem is in web.xml, which I understood not to have influence for socket handling. However having web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
 <display-name>SocketPOC</display-name>

 <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
 </servlet-mapping>

</web-app>

My socket stops working. When I delete servlet-mapping flags:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
 <display-name>SocketPOC</display-name>

</web-app>

it works back again. I would like to have it both - like I would like to server html files via this server and handle sockets in parallel. What am I doing wrong?

Tomcat version 8.0.33 jre 1.9.0_91 I'm running it under eclipse Luna (if it changes anything).

  • 1
    Just a short notice, that static can be served via entry in server.xml (http://stackoverflow.com/questions/1812244/simplest-way-to-serve-static-data-from-outside-the-application-server-in-a-java), also I have a apache before tomcat (so that's another layer to serve static context). Finally I could implement a class to serve it too. However still I would like to understand what is wrong with attribute in web.xml (as I thought web.xml has no influence on websockets). – parvuselephantus Jul 02 '16 at 10:19
  • I believe 'default' is reserved for the default servlet, unless you're going to provide the same functions plus more. Try something else. – user207421 Oct 21 '21 at 08:51

2 Answers2

0

After some testing I got it to work renaming the servlet to "default2" instead like

<servlet-mapping>
    <servlet-name>default2</servlet-name>
    <url-pattern>/index.html</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>default2</servlet-name>
    <servlet-class>
      org.apache.catalina.servlets.DefaultServlet
    </servlet-class>
    <init-param>
        <param-name>listings</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

using a tomcat 8.5.57

FelixD
  • 75
  • 7
0

As you remark the Servlet and Websocket API are mostly independent and there might even be standalone WebSocket containers.

When a container offers both the Servlet API and Websocket API, the Websocket implementations usually relies on the Servlet implementation and some restrictions might arise.

Tomcat's websocket implementation installs a Filter (WsFilter) bound to /* in your application. This filter intercepts all requests and if they match a websocket Endpoint it redirects it to the endpoint.

However the filter will only be called if there is a servlet willing to process the request. Usually the default servlet processes all requests that are not processed by other servlets, but you changed its URL pattern to *.html. All requests, whose URI does not end up in .html (like /echo) will not even be routed to your application and they will receive a non-customized 404 Not Found error.

Since there is no reason to change the binding of the default servlet (all resources that should not be accessible on the web, should be in the /WEB-INF folder anyway), the issue in your question is more of a curiosity than a real problem.

Piotr P. Karwasz
  • 12,857
  • 3
  • 20
  • 43