I have a vaadin application and I am trying to provide some REST Urls provided by spring MVC alongside - my web.xml is below. I only get 404s at /info - it seems like Vaadin steals all the url patterns.
If I remove Vaadin, I can reach /info and get content at that url. How to I get them to play nicely together?
<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>
<context-param>
<description>Vaadin production mode</description>
<param-name>productionMode</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<servlet-name>Vaadin Application Servlet</servlet-name>
<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
<!-- replace standard applicationServlet with the ICEpush one -->
<!--<servlet-class>org.vaadin.artur.icepush.ICEPushServlet</servlet-class>-->
<init-param>
<description>Vaadin application class to start</description>
<param-name>application</param-name>
<param-value>myapp.vaadin.MyVaadinApp</param-value>
</init-param>
<init-param>
<param-name>widgetset</param-name>
<param-value>myapp.gwt.MyAppWidgetSet</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Vaadin Application Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Vaadin Application Servlet</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>info</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>info</servlet-name>
<url-pattern>/info</url-pattern>
</servlet-mapping>
The url-pattern for the Vaadin servlet is /* which is a wild-card for everything so that servlet will handle every request. One option is to narrow the urls for the Vaadin servlet to something more specific than /*.
The forum entry Tom referred to is here: https://vaadin.com/forum/#!/thread/344236/376324
It helped me but I did it a bit differently:
@WebServlet(urlPatterns = {"", "/VAADIN/*", "/UIDL"}, asyncSupported = true)
(i.e no need for a index jsp page) See also the vaadin book section 4.8.5 .
("/UIDL/" doesn't work http://dev.vaadin.com/ticket/7386 and "/UIDL" is a 'Suspicious url pattern... see sections 12.1 and 12.2 of the Servlet specification')
In the end after a lot of fighting I had to stick the webservices under its own subpath:(
http://.../r/...
For completeness I'm pasting the forum info (from Bobby) which helped me here:
In case it's not obvious how this works, a url pattern like "/info/a" does not match "/info" but it does match "/*" since the wildcard would match with anything (in this case * == "info/a"). Given two patterns like "/" and "/info/", the rule is that the longest match wins, so the second one wins.
I'm currently using Vaadin as the UI front end on a service that provides REST URLs for various things. In my case I wanted to put the web app at /ui and have everything else be for the REST services. But, if a user comes to the main page, I want him/her to be shown the UI. This worked fine for me, and I'm sharing it in case anyone is curious about how the mapping works. A similar pattern, for instance, could be used to map /* to Vaadin but /login.jsp to a JSP if you're using form-based authentication.
In my case, I'm using Java EE 6 so I have the Vaadin mappings in a servlet class like this. The mappings could just as easily be in web.xml:
@WebServlet(urlPatterns = {"/ui/*", "/VAADIN/*"})
public static class MyServlet extends AbstractApplicationServlet {
// ...
}
Then web.xml contains:
<servlet>
<!-- technically, a JSP is a servlet -->
<servlet-name>index</servlet-name>
<jsp-file>index.jsp</jsp-file>
</servlet>
<servlet>
<!-- this is the Jersey REST servlet -->
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- We'll map / to the welcome page and /* to our resources. -->
<servlet-mapping>
<servlet-name>index</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
So I have it set up that /* will match to any REST resource I add, as long as it's not /ui/*. When a user first comes to the site, s/he is directed to index.jsp, which is simply:
That's probably a lot more than you want to know, but maybe it will help someone. If the UI is a minor part of the web application, then I like having it sit at a specific URL rather than using /* for it.
Thanks to help from Vaadin forum the answered turned out to be to use /info/* rather than /info. Sorry - I didn't make it easy to answer as I initially forgot to include the /info servlet in the question!
来源:https://stackoverflow.com/questions/5394179/how-to-stop-vaadin-stealing-all-url-patterns-and-play-nicely-with-spring-mvc