Multiple Vaadin apps, JSPs and 3rd party servlets in a same project

Hi! I’m converting a Vaadin Framework project with

  • multiple path specific servlets for different Vaadin apps
  • JSPs
  • 3rd party servlets like barcode4j

to Vaadin Flow 24.

So, I need to get these URLs working:

The converted project is based on base-starter-gradle.

With VaadinServlet URL pattern /vaadin/* and @Route("app-1") and @Route("app-2")

work fine but aren’t feasible because /vaadin-app-1 and /vaadin-app-2 are stored in bookmarks, documents etc.

It is possible to

  • extend VaadinServlet → App1Servlet & App2Servlet with URL patterns /vaadin-app-1/* and /vaadin-app-2/*
  • set @Route("") for App1Component and App2Component

but is it possible to assign App1Component to App1Servlet and App2Component to App2Servlet? How?

You could use your reverse proxy in front of your application to automatically rewrite the URLs and inform your users that they should update their bookmarks.

@knoobie, thanks. That’s an option, but I’d rather implement this inside a war package if possible.

After implementing this method in the both servlet classes

@Override
protected VaadinServletService createServletService() throws ServletException {
    VaadinServletService service = null;
    try {
        service = super.createServletService();
        RouteConfiguration config = RouteConfiguration.forRegistry(service.getRouter().getRegistry());
        config.setRoute("", App1Component.class); // App2Component.class in another servlet
    } catch (ServiceException e) {
        throw new ServletException(e.getMessage(), e);
    }
    return service;
}

the following exception is thrown:

com.vaadin.flow.server.AmbiguousRouteConfigurationException: Navigation targets must have unique routes, found navigation targets ‘com.example.App1Component’ and ‘com.example.App1Component’ with the same route.

→ Maybe it is not possible to implement what was requested.

If the Vaadin “apps” single views (e.g. you land on /vaadin-app-1 and there are no other views like /vaadin-app-1/something), and the concern is limited to links stored somewhere, you can perhaps setup a Servlet Filter to perform a permanent redirect, e.g. from /vaadin-app-1 to /vaadin/app-1.

Another potential solution, assuming third-party servlets have specific mappings, could be to have a custom Vaadin Servlet mapped to /*, that forwards JSPs to the default servlet (or you can map the default servlet to *.jsp in web.xml). However, this solution would be specific to the servlet container. For example, with Jetty you can probably do something like

@WebServlet(asyncSupported = true, urlPatterns = {"/*", "/VAADIN/*"})
public class MyVaadinServlet extends VaadinServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (request.getRequestURI().endsWith(".jsp")) {
            request.getServletContext().getNamedDispatcher("jsp").forward(request, response);
        } else {
            super.service(request, response);
        }
    }
}

Thank you @marcoc_753! request.getServletContext().getNamedDispatcher("jsp").forward(request, response) seems to work in Tomcat also.