Vaadin 7 Servlet Mapped to Root Fails to Recognize UIDL Request Type

With Vaadin 7.0.4, I mapped my servlet to “/”. I also have resource mappings for /VAADIN/* and /UIDL/* so that Vaadin gets to process requests of these kinds. Presumably I also need to add HEARTBEAT and other kinds, but I am now concerned with UIDL.

However, in this setup, UIDL requests are interpreted by Vaadin as having a request type of OTHER. This in turn means I cannot use my application on its root path. This looks like a regression of this issue: http://dev.vaadin.com/ticket/7386.

The culprit is in ServletPortletHelper.hasPathPrefix, which returns null on a null path info. Perhaps I can do some Jiu Jitsu on the request wrapping it so that it is not null, but I don’t know if that is contrary to the JEE specs and I would rather not. Is this a known issue, and are there workarounds without sacrificing the rootness or rootnicity or rootification of my app?

With apologies, this seems to be a Tomcat issue or perhaps a limitation in the servlet spec. If the servlet is mapped as / or if it is used as / by virtue of the welcome file list technique (map servlet to /foo, list foo as a welcome file in web.xml, then point your browser to / instead of /foo), then Tomcat’s request object will report the following for a request like /UIDL: servletPath=/UIDL, pathInfo=/ (or empty, I don’t remember now) instead of the expected: servletPath=/, pathInfo=UIDL/. This prevents Vaadin from recognizing the request types as such.

The solution for me is as follows:

  1. Extend VaadinServlet and configure my subclass as the vaadin servlet.
  2. Override service(HttpServletRequest, HttpServletResponse) and wrap the request in my own class, say, MyRequest.
  3. MyRequest extends HttpServletRequestWrapper and overrides getServletPath and getPathInfo as follows: if I recognize the request as being issued on / (in my case, because super.getServletPath() does not start with /foo), I make getServletPath return / and getPathInfo return super.getServletPath() + super.getPathInfo(). Otherwise, return the super values unchanged.

I hope this helps someone else. This is a servlet container thing, not a Vaadin thing.

In any case, my full servlet configuration calls for mapping all of the following to the servlet: /foo /foo/* /UIDL/* /VAADIN/* /APP/* /HEARTBEAT/*. Further, I make foo a welcome-file and point my browser to my app without foo in the URL.