Skip to content

Vaadin and Spring MVC in parallel

WARNING!

Recently Vaadin and Spring can run in parallel by default by using the newest Vaadin Spring add-on https://vaadin.com/directory#!addon/vaadin-spring which also has an easy set up tutorial using http://start.spring.io so this article is to be considered "deprecated".

Abstract

Sometimes it is needed to create a REST webservice to allow access to your APIs from external applications. I found that with Vaadin servlets I cannot use anything similar to Spring's @ResponseBody, so using Spring in parallel to handle that aspect would come quite in handy. In this brief note I'll explain a quick way to do a basic configuration to get Spring MVC running in parallel with Vaadin.

I'm going to assume you know how to use Spring MVC's controllers and Vaadin, in general.

Adding Spring to the project

Library

The first thing to do is to add the dependencies of Spring-MVC to the project. Only one library is required: org.springframework.spring-webmvc.

Servlet configuration

The second step is to configure a servlet to answer user's calls. To do this, we will edit/create a web.xml file in the WEB-INF directory. Its content will be simple enough:

<?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_2_5.xsd" version="2.5">
<display-name>SPRING AND VAADIN IN PARALLEL</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
</param-value>
</context-param>

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

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

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

</web-app>

Now you'll have to insert the simple configuration files for spring into the specified directories (in this case, as you can see from the xml, they are in /WEB-INF/spring/servlet-context.xml and /web-inf/spring/root-context.xml

The following are the configurations that I used in those two XMLs

root-context.xml features no real configurations

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

<!-- Root Context: defines shared resources visible to all other web components -->


</beans>

whereas servlet-context.xml only specifies that we're using the annotation configuration of Spring MVC, and where to pick the controllers

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven /><!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<context:component-scan base-package="com.example.vaadintest.controllers" /></beans:beans>

Unwire Vaadin

Now that Spring MVC is configured, you want to get rid of Vaadin answering to every call ("/*") and point it only on specific paths.

Get your Vaadin UI class and change the servlet mapping:

@WebServlet(urlPatterns = {"/app/*", "/VAADIN/*"}, asyncSupported = true)

Note that I used both /app/* and /VAADIN/* because otherwise Spring would answer when Vaadin searches for its compiled javascript or themes, and we don't want that, because it renders the application unusable.

Conclusion

That's it. Now Vaadin will only answer to a direct /app call, and the rest will be controlled by Spring. If you want to tie the index page to Vaadin then you just need a simple redirect function inside a Spring controller, like this:

@Controller
public class RedirectController {
@RequestMapping("/")
public String redirectHomeToApp() {
return "redirect:/app";
}
}

Hope this will help you, if you encounter any problem contact me via the contacts module!

Flash