Introduction
This is Vaadin Framework's add-on to integrate Spring Framework. It's the most popular add-on for Vaadin 7+ in the World :-)
Features
- Spring Framework integration
- No AOP dependencies!
- Vaadin's Views Autowiring
- Vaadin's Views caching
- Vaadin's SystemMessages customization
- Apache Shiro integration
- Portlet support
- Initial OSGI support
Quick start
Maven's pom.xml
<repositories>
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>ru.xpoft.vaadin</groupId>
<artifactId>spring-vaadin-integration</artifactId>
<version>3.2</version>
</dependency>
</dependencies>
web.xml
<servlet>
<servlet-name>Test Application</servlet-name>
<servlet-class>ru.xpoft.vaadin.SpringVaadinServlet</servlet-class>
<init-param>
<param-name>beanName</param-name>
<param-value>myUI</param-value>
</init-param>
</servlet>
<!-- Bind as an ordinary VaadingServlet -->
<servlet-mapping>
<servlet-name>Test Application</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Test Application</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
MyUI.java
@Component
@Scope("prototype")
@Theme("myTheme")
public class MyUI extends UI
{
private static Logger logger = LoggerFactory.getLogger(TrackerUI.class);
@Autowired
private transient ApplicationContext applicationContext;
@Autowired
private MyClass myClass;
....
}
Sample project
Description
Vaadin's Views Autowiring
Vaadin Navigator. Standard way
// Create a navigator to control the views
Navigator navigator = new Navigator(this, this);
// Create and register the views
navigator.addView("main", new MainView());
navigator.addView("test", new TestView());
public class TestView extends VerticalLayout implements View {
...
}
public class MainView extends VerticalLayout implements View {
...
}
New DiscoveryNavigator. It can autowiring views.
Use @VaadinView for views to set uri.
// Create a navigator to control the views
DiscoveryNavigator navigator = new DiscoveryNavigator(this, this);
@Component
@Scope("prototype")
@VaadinView(TestView.NAME)
public class TestView extends VerticalLayout implements View {
public static final String NAME = "test";
...
}
@Component
@Scope("prototype")
@VaadinView(MainView.NAME)
public class MainView extends VerticalLayout implements View {
public static final String NAME = "main";
...
}
Vaadin's Views caching
You can cache a View instance for UI. It something like "Vaadin UI" scope for a View. The View creates only once for an UI instance.
@VaadinView(..., cached = true)
@Component
@Scope("prototype")
@VaadinView(value = UIScopedView.NAME, cached = true)
public class UIScopedView extends Panel implements View
{
...
@Override
public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent)
{
...
}
}
Vaadin's SystemMessages customization
You can use Spring MessageSource as source for Vaadin SystemMessages.
And wow! Now you can use localized messages!
You should reload page after changing language. Texts for CommunicationError and AuthenticationError implements on page loading. It's Vaadin.
Use default SpringSystemMessagesProvide
web.xml
<servlet>
<servlet-name>Vaadin Application</servlet-name>
<servlet-class>ru.xpoft.vaadin.SpringVaadinServlet</servlet-class>
...
<init-param>
<param-name>systemMessagesBeanName</param-name>
<param-value>DEFAULT</param-value>
</init-param>
</servlet>
in your Spring messages
vaadin.sessionExpired.Caption = ...
vaadin.sessionExpired.Message = ...
vaadin.sessionExpired.URL = ...
vaadin.sessionExpired.NotificationEnabled = ... (true / false)
Other message types: communicationError, authenticationError, internalError, outOfSync, cookiesDisabled
vaadin.communicationError.Caption = ...
If some translations don't found, it will use default Vaadin message. So you can translate "caption" only, for example.
Use your bean (more difficult way)
web.xml
<servlet>
<servlet-name>Vaadin Application</servlet-name>
<servlet-class>ru.xpoft.vaadin.SpringVaadinServlet</servlet-class>
...
<init-param>
<param-name>systemMessagesBeanName</param-name>
<param-value>customSystemMessages</param-value>
</init-param>
</servlet>
CustomSystemMessages class must implements SpringSystemMessagesProvider interface.
Apache Shiro integration
Use ShiroSecurityNavigator instead of DiscoveryNavigator. ShiroSecurityNavigator supports annotations @RequiresRoles, @RequiresPermissions, @RequiresAuthentication, @RequiresGuest, @RequiresUser for a View class. If user doesn't have permission, the View is not visible.
ShiroSecurityNavigator in UIShiroSecurityNavigator navigator = new ShiroSecurityNavigator(this, getContent());
View example
@Component
@Scope("prototype")
@VaadinView(RoleUserView.NAME)
@RequiresRoles("user")
public class RoleUserView extends Panel implements View
{
public static final String NAME = "role_user";
...
}
Portlet support
portlet.xml
<portlet>
<portlet-name>Test Portlet</portlet-name>
<display-name>Test Portlet</display-name>
<portlet-class>ru.xpoft.vaadin.SpringVaadinPortlet</portlet-class>
<init-param>
<name>beanName</name>
<value>myUI</value>
</init-param>
<!--
To enable displaying multiple Vaadin portlets on a page,
they should all use the same widgetset. In that case, the
widgetset can be configured on the portal level (parameter
vaadin.widgetset) or here for each portlet.
-->
<!--
<init-param>
<name>widgetset</name>
<value>com.vaadin.portal.gwt.PortalDefaultWidgetSet</value>
</init-param>
-->
<!-- Supported portlet modes and content types. -->
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<!-- <portlet-mode>edit</portlet-mode> -->
<!-- <portlet-mode>help</portlet-mode> -->
</supports>
<!-- Not always required but Liferay uses these. -->
<portlet-info>
<title>Test Portlet</title>
<short-title>Test Portlet</short-title>
</portlet-info>
</portlet>