Professional Documents
Culture Documents
of Contents
Introduction 1.1
Project setup 1.2
Command Line 1.2.1
IntelliJ IDEA 1.2.2
Eclipse 1.2.3
NetBeans 1.2.4
Plugin Configuration 1.2.5
Clean up 1.2.6
Best Practices 1.2.7
Database 1.3
GORM 1.3.1
Create Domain Model 1.3.1.1
Transactions 1.3.1.2
LazyInitializationException 1.3.1.3
Open Session In View I. 1.3.1.4
Open Session In View II. 1.3.1.5
Table Container 1.3.1.6
Groovy SQL 1.3.2
Create Sql 1.3.2.1
Execute SQLs 1.3.2.2
MyBatis 1.3.3
Configuration 1.3.3.1
Basics 1.3.3.2
JdbcTemplate 1.3.4
Create Beans 1.3.4.1
Usage 1.3.4.2
Clean Up With Alternatives 1.3.5
Architecture 1.4
Model View Presenter 1.4.1
Spring Autowiring 1.5
2
Create Simple Application 1.5.1
Application With Navigator 1.5.2
UI 1.6
Re-using GORM Validations 1.6.1
Async Push 1.6.2
Multiple application 1.6.3
SASS Compilation 1.6.4
Widgetset Compilation 1.6.5
Spring Security 1.7
Spring Security Dependency 1.7.1
Spring Security Basics 1.7.2
Secured Navigator 1.7.3
Localization 1.8
Localization Basics 1.8.1
Custom MessageSource 1.8.2
REST 1.9
Without using root URL 1.9.1
Using root URL for Vaadin app 1.9.2
Plugin development 1.10
Github 1.10.1
Development 1.10.2
3
Introduction
Vaadin on Grails
The book describes how to create project, setup configuration, what code is created
automatically and how to clean up the code that will become useless when we use Vaadin
for user interface.
We will go through two approaches how to work with database. The first one is GORM,
which is the default option. And then few alternatives to GORM that are MyBatis,
JdbcTemplate and Groovy Sql.
We will look at data binding tricks, basic ideas for architecture and how to compose the
components using Model View Presenter (MVP).
The book also contains tutorials how to compile SASS and widget set, after you add an add-
on. How to use Spring security, localization and how to add a REST API from a Vaadin
application and many other things.
If you are completely new to both technologies, the book will show you first steps to start up
and then you can continue with Vaadin and Grails documentation.
If you are both Vaadin and also Grails expert, you might look at the book as a reference
book, set of tutorials and also a place with several solutions that you might have to solve in
your applications.
Questions you have been asking during last few years about development of Vaadin
using Groovy and Grails.
Many years spend with development of applications using Grails and Vaadin.
Chapter about Grails in Vaadin 7 Cookbook that showed there is more to discover.
Vaadin
Vaadin provides both simple and complex web UI components that can be displayed in
browser or in mobile app, while the client side, an applicaiton running inside a web browser,
is still connected to the server and communication happens when required, after user's
action or when server pushes data to the client from the server.
4
Introduction
Developers who like object oriented programing and design patterns that result in
predictable APIs, might feel excited about the way how the development of an user interface
can be done with Vaadin. We can play with UI components and still keep thinking about it as
object structures in Java.
Grails
Grails 2.x is supported in the book. Support for Grails 3.x is comming soon.
Grails is framework used to build applications in really short time, because it provides:
Dependency management
Dependency injection with Spring application context
URL mapping
Filters
Controllers
Groovy Server Pages (.gsp) & tags
AJAX support
REST, SOAP
GORM (Grails ORM)
Transactional service layer
Async behavior
Internationalization i18n
Environments
Using Groovy and Java languages
Groovy-powered Gant command line
On the fly reloading
The most useful feature of Grails might be GORM (Grails Object Relation Mapping) that
makes really easy to create a database layer. Then there are services, which support
transactions, that are the place to put the application logic.
5
Introduction
issues and implementation of business logic rather than spend time on implementation of
JavaScript components. If that is the case, we could choose Vaadin to implement our Rich
Internet Applications (RIA).
Vaadin plugin
There is a Grails plugin called vaadin that integrates Vaadin into Grails realm, by providing
dependencies to Vaadin libraries. Also, the plugin provides some support for development.
6
Project setup
Project setup
We are going to learn how to create and configure Grails application with Vaadin plugin in
this chapter.
First we need to get Grails installed on your local machine. Type grails --version in your
console in order to make sure you have the latest version, because Vaadin plugin is always
updated to work with latest version of both Vaadin and Grails frameworks.
If Grails is not on your local and you need some help with installation, follow these tutorials.
Mac OS X
http://www.grailsexample.net/installing-a-grails-development-environment-on-os-x
Windows
http://www.grailsexample.net/installing-a-grails-development-environment-on-windows
7
Project setup
Linux
http://www.grailsexample.net/installing-a-grails-development-environment-on-linux
8
Command Line
Command line
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.
Using Grails command line to create a new application is probably the most reliable way. We
can basically say that if you are not able to create project using the command line, you will
be not able to work with Grails at all and you need to re-install Grails or fix its configuration.
Create application
These instructions are supposed to be executed by using the command line.
Step 1
Open your console and run grails create-app my-app that will create new directory called
my-app with sample Grails application.
Step 2
Go to that directory cd my-app and open that folder in a text editor of your choice.
Step 3
Open BuildConfig.groovy and add latest version of vaadin plugin into compile scope
compile ":vaadin:7.6.1" .
9
Command Line
Step 4
Now we need to run grails vaadin-quickstart , so Vaadin plugin can generate sample
application for us.
Step 5
We want to prevent Grails to take over URL mapping. Open UrlMappings.groovy and make
sure the URL mapping is empty.
class UrlMappings {
static mappings = {
}
}
Step 6
10
Command Line
We are ready to start up the application. Run grails run-app command. Vaadin application
running on http://localhost:8080/my-app will become accessible after a while.
11
IntelliJ IDEA
IntelliJ IDEA
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.
Grails support in IntelliJ IDEA is added through Grails plugin. Make sure it is installed in your
IntelliJ IDEA before you start with the tutorial.
Step 1
Go to http://grails.org/download and get the latest version of Grails. Unpack the Grails
archive on your local computer and start up IntelliJ IDEA.
Step 2
Open the New Project window and select Grails from the list and click on Next button.
Optional
If it is your first Grails project in IDEA, click on Create... button and then select the root of
your unpacked Grails archive. It will add Grails into IDEA.
Step 3
Fill in the name of the project and choose the latest version of Grails.
12
IntelliJ IDEA
Step 4
Click on Finish and on the next dialog, choose Run 'create app' .
Warning: sometimes, IDEA is not able to create Grails project and you end up with
weird errors. In that case, try to upgrade IDEA version or run grails create-app my-app
in console. Then after that open the project in IDEA.
Step 5
Open file BuildConfig.groovy and add Vaadin plugin compile ":vaadin:7.6.1" .
13
IntelliJ IDEA
Now we need to tell IDEA to reload dependencies. Run grails compile or refresh the
dependencies as shown on the following picture.
Synchronize Grails setting should be performed always when you run into issues with
dependencies.
Step 6
Run grails vaadin-quickstart that will generate sample code to easier project
configuration.
14
IntelliJ IDEA
The command vaadin-quickstart will generate MyUI.groovy and remove URL mapping
inside UrlMapping.groovy .
Optional
We have to disable Grails to take control over the URLs, so Vaadin can do it instead. Open
UrlMappings.groovy file and make sure the URL mapping is empty, so the content of the file
is the following.
class UrlMappings {
static mappings = {
}
}
Step 8
We are ready to run the application. Click on the little green triangle in toolbar.
You can also press Alt+Cmd+G on Mac OS or Ctrl+Alt+G on Windows and type run-
app in order to run the application.
Step 9
15
IntelliJ IDEA
Run the application again and a Vaadin application with a single Home label will be available
on http://localhost:8080/ria-app in your browser.
16
Eclipse
Eclipse
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.
Spring provides great tool Groovy/Grails Tool Suite for development of Groovy and Grails
based projects. If Eclipse is your development IDE, you should definetelly get GGTS.
We will show how to create a new Grails project with Vaadin using GGTS in this article.
Step 1
Search for Grails type of project in New Project wizard and click on Next .
Step 2
Type a name of the project and click on Finish .
17
Eclipse
Step 3
Open file BuildConfig.groovy and add Vaadin plugin compile ":vaadin:7.6.1" .
18
Eclipse
Run grails compile to reload dependencies. Click on Grail icon in GGTS and type there
compile .
Then run grails vaadin-quickstart that will generate sample code to easier project
configuration.
The command vaadin-quickstart will generate MyUI.groovy and remove URL mapping
inside UrlMapping.groovy .
Optional
We have to disable Grails to take control over the URLs, so Vaadin can do it instead. Open
UrlMappings.groovy file and make sure the URL mapping is empty, so the content of the file
is the following.
19
Eclipse
Step 6
Click on Grail icon again and run run-app command.
Step 7
Now your application is running on http://localhost:8080/my-app
20
NetBeans
NetBeans
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.
Then you need to install Grails plugin for NetBeans. Search for grails and mark Groovy
and Grails plugin as selected.
Click on Install button and finish the instalation which will require restart Netbeans IDE.
Step 1
Open New Project window to create Grails application. Select Grails Application and
click on Next .
21
NetBeans
Step 2
Type name of the project and finish the wizard.
Also configure Grails version that will be used for your project.
22
NetBeans
Step 3
Open BuildConfig.groovy and add dependency to vaadin plugin compile ":vaadin:7.6.1" .
23
NetBeans
Run grails compile command. It will download Vaadin plugin together with all mandatory
dependencies.
Then click on Refresh Commands button and run grails vaadin-quickstart that will generate
sample code to easier project configuration.
The command vaadin-quickstart will generate MyUI.groovy and remove URL mapping
inside UrlMapping.groovy .
24
NetBeans
Optional
We want to prevent Grails to take over URL mapping. Open UrlMappings.groovy and make
sure the URL mapping is empty.
class UrlMappings {
static mappings = {
}
}
Step 5
We are ready to start up the application. Run grails run-app command.
25
NetBeans
26
Plugin Configuration
Basics
When we add dependency to Vaadin plugin into BuildConfig.groovy and run grails
compile the plugin generates the following files inside our Grails application.
MyUI.groovy
Sample UI class src/groovy/app/MyUI.groovy which contains code that just shows a label in
the web browser.
We can immediatelly start coding Vaadin application using that file, or maybe rather do a
refactoring. For example, rename the file to AppUI.groovy and move it to different package
(folder) src/groovy/com/company/app . Then you need to change mapping property inside
VaadinConfig.groovy .
VaadinConfig.groovy
Vaadin configuration file grails-app/conf/VaadinConfig.groovy contains all the configuration
that is required by the plugin.
mapping
We can provide multiple Vaadin UI classes that extends com.vaadin.ui.UI and they will be
mapped to specified URL patterns. There must be at least one UI class.
Let's look at this example where we map three URL paters, each to separate UI class.
mapping = [
"/*": "app.MyUI",
"/admin/*": "app.AdminUI",
"/client/*": "app.ClientUI"
]
http://localhost:8080/grails-vaadin7-demo
http://localhost:8080/grails-vaadin7-demo/client
http://localhost:8080/grails-vaadin7-demo/admin
27
Plugin Configuration
Be aware, creating multiple UIs is not the way how to navigate in the Vaadin applicatin.
Use views navigator for this.
mappingExtras
We need to define extra mapping in case we need to 'reserve' a URL that should not be
mapped to, for example, /* by Vaadin.
For example, we need to enable console plugin. First we add plugin dependency compile
":console:1.4.4" into BuildConfig.groovy .
mappingExtras = [
'/console/*'
]
productionMode
When production mode is set to false, it enables debug mode. So, we can easily inspect
application in browser by adding ?debug to the end of URL.
productionMode = false
In order to enable productionMode in production, make sure the following code is present.
environments {
production {
vaadin {
productionMode = true
}
}
}
asyncSupported
Set this property to true to enable asynchronous communication, so you can use Vaadin
push.
28
Plugin Configuration
asyncSupported = true
themes
You can provide name of the themes, which is a directory name in web-app/VAADIN/themes
folder.
themes = ['sample']
sassCompile
You can specify exact version of Vaadin for SASS compilation.
sassCompile = '7.6.1'
widgetset
In order to use your own widget set, for example, if you need to use add-ons.
widgetset = 'com.mycompany.widgetset'
If widgetset is not set, the default widget set from Vaadin is used.
servletClass
There is a default servlet, com.vaadin.grails.server.DefaultServlet , provided by Vaadin
plugin that makes actually possible to run Vaadin inside Grails.
servletClass = "com.app.MyGrailsAwareApplicationServlet"
packages
We can define a package name where Spring will search for components.
packages = ['com.mycompany.vaadin']
29
Plugin Configuration
uiProvider
We can create own implementation of com.vaadin.server.UIProvider .
uiProvider = "com.mycompany.MyGrailsAwareUIProvider"
openSessionInViewFilter
In order to activate Open Session in View for Hibernate 3.
openSessionInViewFilter = 'org.springframework.orm.hibernate3.support.OpenSessionInVie
wFilter'
openSessionInViewFilter = 'org.springframework.orm.hibernate4.support.OpenSessionInVie
wFilter'
30
Clean up
Clean up
Grails create-app command generates many code we do not really need in the application.
Let's clean it up.
Remove assets
We can remove grails-app/assets folder because all required assets are provided by
Vaadin.
Remove views
When we use Vaadin as UI framework, we need no .gsp pages in our application. We can
remove grails-app/views .
Dependencies
There are not needed dependencies if we use Vaadin. We can exclude them globaly.
grails.project.dependency.resolution = {
inherits("global") {
'grails-plugin-gsp', 'grails-plugin-rest', 'grails-resources'
}
Verify what has been excluded by running grails dependency-report command. You
can add a scope as the parameter, for example, grails dependency-report compile ,
grails dependency-report runtime and so on. In order to be sure that a dependency is
The second step in clearing dependencies is to remove all dependencies and plugins that
are generated by Grails. Dependencies and plugins part of BuildConfig.groovy will then
become like this.
31
Clean up
dependencies {
}
plugins {
build ":tomcat:7.0.55"
compile ":vaadin:7.2.5"
}
Last step
Grails generates inline comments for almost each property trying to explain what is the
purpose of that property. I think if somebody wants to know what is the meaning of a
property, he should go to documentation, read about it and fully understand what is it about.
Therefore I suggest to remove these comments.
32
Best Practices
Best Practices
CompileStatic
Use @CompileStatic annotation everywhere you can. The exception not to use the
annotation is dynamic code where you need to utilize dynamic features of Grails, for
example, to access variables that are not visible during compilation.
Types
Use def only when it is required, because it always good to know type of a variable.
Together with @CompileStatic annotation, you will know about compilation errors during
compilation, not during runtime.
33
Database
Database
We will explore two ways how to access database from Grails together with Vaadin. The first
one is GORM (Grails Object Relation Mapping), which is the defualt way to access database
in Grails.
The second part will show how to integrate Grails with other than GORM database
frameworks and how to use it in Vaadin.
34
GORM
GORM
Grails Object Relational Mapping (GORM) provides easy way to define your database mode
and it comes for free with Grails.
Usually the only place you need to configure, to get GORM working with your database, is
DataSource.groovy . Grails will create bean dataSource that will be used for fetching data
from database and that will reflect data source configuration you have set there.
If you want to provide external configuration file, for example you deploy application to
several production environments, you can define external config and set the data
source configuration there.
35
Create Domain Model
Grails documentation has nice description how to work with domain classes. In case you are
new to Grails domain classes, you should definitelly read it.
Anyway, let's show an example how to create a domain object and use it in Vaadin
application.
Step 1
Run Grails create-domain command that will create the new domain class Item .
Step 2
Before we start testing the domain class, we need to add there at least one field, for
example, a string label .
package com.app
class Item {
String label
static constraints = {
}
}
Step 3
Now, we need to create few records of Item in the database during the application start-up.
36
Create Domain Model
import com.app.Item
class BootStrap {
def destroy = {
}
}
Step 4
Use domain class to fetch all records from the database and display them in the browser.
import com.app.Item
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
@Override
protected void init(VaadinRequest vaadinRequest) {
setContent(layout)
}
}
37
Create Domain Model
38
Transactions
Transactions
Example code is available on github.com/vaadin-on-grails/gorm-transactions.
Grails service layer is the proper place to put all the application logic. Services are
transactional and also good place to make your applications code reusable.
In this article will show how to store user with a new account in a transaction. So, when
account is saved but saving user fails the transaction is rolled back. That results in scenario
that nothing is storred, user nor account.
Step 1
Create domain class that represents an account: grails create-domain-class
com.myapp.Account .
class Account {
static constraints = {
}
}
Step 2
Create domain class that represents an user that will have a reference to an accont: grails
create-domain-class com.myapp.User .
class User {
String username
String password
static constraints = {
}
}
Step 3
39
Transactions
In this step we create AccountService that will be transactional, meaning that all methods in
the service will be executed in a transaction. When an exception that extends
RuntimeException is thrown, the transaction will be rolled back automatically.
import grails.transaction.Transactional
@Transactional
class AccountService {
Step 4
Create a view that will execute createUserWithAccount with dummy values. After the method
is executed, try to fetch values from database and print it into the console to see nothing is
stored in database because we let the transaction fail.
40
Transactions
package app
import com.myapp.Account
import com.myapp.AccountService
import com.myapp.User
import com.vaadin.grails.Grails
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Button
import com.vaadin.ui.VerticalLayout
@Override
void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
try {
accountService.createUserWithAccount('test', 'password')
} catch (Exception e) {
println "failed: ${e.message}"
}
println Account.findAll()
println User.findAll()
}
})
addComponent(btn)
}
}
Step 3
In order to test the behavior, we can use the account view in MyUi class.
41
Transactions
package app
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
@Override
protected void init(VaadinRequest vaadinRequest) {
navigator.addView(AccountView.VIEW_NAME, AccountView)
navigator.navigateTo(AccountView.VIEW_NAME)
}
}
When we run the application and a runtime exception is thrown in the service method, we
should see no database items fetched from the database. Have a look the console output to
see what has happend.
We will see that rows has been inserted into the database. Have a look the console output to
see what has happend.
[com.myapp.Account : 1]
[com.myapp.User : 1]
42
Transactions
43
LazyInitializationException
LazyInitializationException
Example code is available on github.com/vaadin-on-grails/gorm-
LazyInitializationException.
When we create a domain model that will cause lazy loading of other domain object, we
might run into the troubles with LazyInitializationException .
The Issue
In order to fully understand, lets show the code simulates LazyInitializationException .
class Account {
String name
static constraints = {
}
}
Now create class User that will belong to Account and in toString() method, just try to
get value from account field. When that code is executed, Hibernate will try to load an
account from database and will throw LazyInitializationException .
class User {
String username
String password
static constraints = {
}
In order to simulate the issue, here is the Vaadin code that will create a ComboBox with an
instance of User class.
44
LazyInitializationException
userAccount.addItem(item)
layout.addComponent(userAccount)
setContent(layout)
Say to Hibernate to load account together with the user. Add the following code into User
class.
static mapping = {
account lazy: false
}
When you try to execute the application, you the account will be already loaded in
getLabel() method and it will not fail.
This also makes sense from performance point of view, because we will avoid multiple
database calls and the user and account will be loaded together, in single database call.
Another approach is to have open session for each request. Read the next two articles
about Open Session In View to find out how to implement it in your application.
45
Open Session In View I.
disabling of lazy loading is not what we are looking for and we still want to do lazy fetching,
we have to use OSIV (Open Session In View).
Stephan Grundner has implemented adding OSIV filter into the plugin. Thanks to that we
can configure openSessionInViewFilter property in VaadinConfig.grovy .
openSessionInViewFilter = 'org.springframework.orm.hibernate4.support.OpenSessionInVie
wFilter'
openSessionInViewFilter = 'org.springframework.orm.hibernate3.support.OpenSessionInVie
wFilter'
46
Open Session In View II.
In the previous article we have described how to enable OSIV in VaadinConfig.groovy. This
tutorial will show way how to do it in the old way, without configuration.
The other way to use OSIV in Grails with Vaadin is to manually add an extra filter
OpenSessionInViewFilter into web.xml file.
Step 1
Generate project templates in your project. install-templates command will generate
many files inside src/templates folder.
grails install-templates
Leave only web.xml and remove folders artifacts , scaffolding and testing .
Step 2
Add the following filter definition, that will keep session opened during each reqiest, into
generated web.xml .
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
47
Open Session In View II.
We are done. Now we can run the application and Hibernate session will be always opened,
during each Vaadin request.
48
Table Container
Table Container
Example code is available on github.com/vaadin-on-grails/gorm-vaadin-table.
In this tutorial we will show how to display GORM objects in Vaadin Grid.
Step 1
Create a domain object Item with two String fields name and other .
package com.vaadinongrails
class Item {
String name
String other
static constraints = {
}
}
Step 2
Create few records of Item in database in BootStrap.groovy file.
class BootStrap {
Step 3
Create instance of Grid in Vaadin code. We need to do two things to see GORM objects
nicely displayed in the grid:
49
Table Container
2. GORM object contains more fields then we have defined and we have to pick what
columns will be visible. Then we have to remove the others which are not supposed to
be visible.
package app
import com.vaadin.data.util.BeanItemContainer
import com.vaadin.grails.ui.VaadinUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Grid
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import com.vaadinongrails.Item
@VaadinUI(path = '/')
class MyUI extends UI {
@Override
protected void init(VaadinRequest vaadinRequest) {
layout.addComponent(grid)
setContent(layout)
}
}
Step 4
Run application and see the table with GORM objects from database.
50
Table Container
51
Groovy SQL
Groovy SQL
Groovy Sql provides simple way to access database. It can become handy when our
application is supposed to only fetch data and we do not want to utilize Hibernate.
Still, if we need to work with domain objects, it is better to use GORM that provides full
package to perform CRUD operations. This chapter provides information how to utilize
Groovy SQL in Grails application with Vaadin.
52
Create Sql
Create Sql
Example code is available on github.com/vaadin-on-grails/groovy-sql.
We can use Groovy Sql class to access a database. The proper way to create new instance
of Sql class is to define new bean in resources.groovy .
import groovy.sql.Sql
beans = {
sql(Sql, ref('dataSource')) { bean ->
bean.destroyMethod = 'close'
}
}
If, from any reason, you would need to create Sql manually, you can the alternative
approach to create Sql each time before SQL execution.
53
Execute SQLs
Execute SQLs
Example code is available on github.com/vaadin-on-grails/groovy-sql.
In order to execute a query with Groovy Sql just get dataSource bean from the application
context, which we have created it in Create Sql article.
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.grails.Grails
import groovy.sql.GroovyResultSet
import groovy.sql.Sql
@Override
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout()
setContent(layout)
Constructing SQL strings in Java or Groovy code is not easy and it is, for some of us,
annoying. I recommend to use jOOQ library to construct SQL strings.
54
MyBatis
MyBatis
Since GORM is the default Grails database access framework, we need to add extra code to
support MyBatis.
This chapter will show how to configure MyBatis inside Grails framework and how to perform
basic operations.
55
Configuration
Configuration
Example code is available on github.com/vaadin-on-grails/mybatis.
Because Grails is based on Spring, we can use mybatis-spring library to integrate MyBatis
into Grails.
Step 1
Add mybatis and mybatis-spring dependencies into BuildConfig.groovy .
compile 'org.mybatis:mybatis:3.2.7'
compile 'org.mybatis:mybatis-spring:1.2.2'
Step 2
Define new beans in resources.groovy .
location
mapperScannerConfigurer will scan for mappers based on what is defined by
basePackage property
import org.apache.commons.dbcp.BasicDataSource
import org.mybatis.spring.SqlSessionFactoryBean
import org.mybatis.spring.mapper.MapperScannerConfigurer
beans = {
sqlSessionFactory(SqlSessionFactoryBean) {
dataSource = ref("dataSource")
mapperLocations = "classpath:com/app/mappers/**/*.xml"
}
mapperScannerConfigurer(MapperScannerConfigurer) {
basePackage = "com.app.mappers"
}
}
56
Basics
Basics
Example code is available on github.com/vaadin-on-grails/mybatis.
This article shows how to work with MyBatis in Groovy application. We will fetch data from
database and show them on UI.
Step 1
Create Item class that will represent a database entity. This class will be used by MyBatis
as a data transfare object. MyBatis will automatically fetch values from database in to an
instance of Item class.
package com.app.mappers
class Item {
Long id
String label
}
Step 2
Create mapper interface for Item class. Then this mapper will be referenced from XML
mapping file.
package com.app.mappers
interface ItemMapper {
Step 3
Create src/groovy/com/app/mappers/ItemMapper.xml XML mapper file and define SQL query
that will be executed when findById method is called.
57
Basics
<mapper namespace="com.app.mappers.ItemMapper">
<select id="findById" resultType="com.app.mappers.Item">
select * from Item where id = #{id}
</select>
</mapper>
Step 4
To try out whether MyBatis is working, create Item database table and insert there a new
record. So, we can fetch it later in Vaadin UI.
import javax.sql.DataSource
import java.sql.Statement
class BootStrap {
DataSource dataSource
statement.close()
}
def destroy = {
}
}
Step 5
Here is an example of how to get the mapper and fetch values from database. Get the bean
from the context Grails.get(ItemMapper) and call the method findById(1) .
58
Basics
package app
import com.app.mappers.Item
import com.app.mappers.ItemMapper
import com.vaadin.grails.Grails
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
@Override
protected void init(VaadinRequest request) {
setContent(layout)
}
}
When grails run-app is executed the application is started, a value Sample is fetched from
database and displayed in the web browser.
59
JdbcTemplate
JdbcTemplate
JdbcTemplate provides simple way to execute SQL queries.
It can prevent your code from SQL injection. You can also provide mappers that will map
result set to your domain classes.
60
Create Beans
Create Beans
Example code is available on github.com/vaadin-on-grails/jdbc-template.
In this article, we will show how to define beans in order to start working with spring-jdbc.
Step 1
Add dependency to spring-jdbc into BuildConfig.groovy .
dependencies {
compile 'org.springframework:spring-jdbc:4.0.6.RELEASE'
}
Step 2
We can use JdbcTemplate to directly execute SQL queries, but if there will be inputs from
users, we have to use ? as a parameter placeholder or rather use
NamedParameterJdbcTemplate to prevent SQL injection.
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
beans = {
jdbcTemplate(JdbcTemplate, ref('dataSource'))
namedJdbcTemplate(NamedParameterJdbcTemplate, ref('dataSource'))
}
61
Usage
Usage
Example code is available on github.com/vaadin-on-grails/jdbc-template.
This article shows a few ways how to use JDBC template by Spring.
usersX.each {
String firstName = it.get('first_name')
layout.addComponent(new Label(firstName))
}
If you use jOOQ for SQL string construction, there is a comfortable way to get named
parameters as a map.
62
Usage
@Override
Object mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(firstName: rs.getString('first_name'))
}
}
Now we can give UserRowMapper to named JDBC template and it will map the result of the
query into a new instance of User class.
layout.addComponent(new Label(usersY.firstName))
63
Clean Up With Alternatives
Before you start excluding and removing dependencies, let's run grails dependency-report
compile command to see what libraries are loaded for compile scope.
Step 1
Remove runtime ":hibernate4:4.x" or runtime ":hibernate:3.x" from
BuildConfig.groovy .
Step 2
Add exclude for grails-plugin-databinding in BuildConfig.groovy .
grails.project.dependency.resolution = {
inherits("global") {
'grails-plugin-databinding'
}
64
Architecture
Architecture
This chapter will show a way to architecture your Vaadin application despite you might
compose your application in various ways using different design patterns.
The reason of this chapter is to show how to create testable Vaadin application following
common patterns.
65
Model View Presenter
This article shows an example of Model View Presenter implementation. The basic idea is to
show a way to split work with domain and service layer and UI view layer, not mixing all
together.
Model represents database entities and provide way to manipulate with them.
View displays UI components and has no context of how the database is used to fetch
data.
Presenter connect Model and View together, while only the presenter has the right to
touch Model.
Step 1
Create domain model class for user entity. Run grails create-domain-class app.model.User
command to create User class.
package app.model
class User {
String firstname
String surname
String email
static constraints = {
}
}
Step 2
Now create service, by running grails create-service app.model.UserService command,
that will be used to manipulate with User domain object.
66
Model View Presenter
package app.model
import grails.transaction.Transactional
@Transactional
class UserService {
Step 3
Persist one user in BootStrap.groovy to have a database record in database. We will use it
later.
import app.model.User
class BootStrap {
}
def destroy = {
}
}
Step 4
Now create a view to display details about user. We will never do any database operations in
UserView class but instead we provide methods to populate values in UI.
67
Model View Presenter
package app.view
import app.model.User
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
UserView() {
setMargin(true)
}
@Override
void enter(ViewChangeListener.ViewChangeEvent event) {
}
We could create an interface for UserView that will define all mandatory methods for
that view. That would easier mocking of UserView in test and could give a way to make
multiple implementations of user view.
Step 5
Now we create presenter for UserView . It will have reference to UserView and
UserService .
The presenter will be responsible to add a view into navigator and to fetch values using
UserService .
68
Model View Presenter
package app.presenter
import app.model.User
import app.model.UserService
import app.view.UserView
import com.vaadin.grails.Grails
import com.vaadin.ui.UI
class UserPresenter {
UserView view
UserPresenter() {
}
void initialize() {
view = new UserView()
UI.current.navigator.addView(USER, view)
}
void navigateTo() {
UI.current.navigator.navigateTo(USER)
Step 6
Now we use UserPresenter in our UI class to display user details.
69
Model View Presenter
package app
import app.presenter.UserPresenter
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
@Override
protected void init(VaadinRequest r) {
new UserPresenter().initialize().navigate()
}
}
Now we can run the application and user will appear in the browser.
70
Spring Autowiring
Spring Autowiring
Managing Vaadin classes in Spring context has been added recently. Please report all
the issues you find.
Recently we have added support for autowiring. That makes Grails.get() method, which
returns beans from application context, useless.
This chapter shows how to configure and create sample application using new annotations
@VaadinUI and @VaadinView .
71
Create Simple Application
In this tutorial, we will create Vaadin application where we can use @Autowired annotation.
Step 1
We need to say the plugin that we want to do annotation based URL mapping. Comment out
mapping from VaadinConfig.groovy to do that.
vaadin {
// mapping = [
// "/*": "app.MyUI"
// ]
}
Step 2
Now we will create a dummy service ItemService that we will autowire in Vaadin code.
package app
import grails.transaction.Transactional
@Transactional
class ItemService {
String serviceMethod() {
return 'Value from service'
}
}
Step 3
Use @VaadinUI annotation to map your UI class to URL.
72
Create Simple Application
package app
import com.vaadin.grails.ui.VaadinUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import org.springframework.beans.factory.annotation.Autowired
@VaadinUI(path = '/')
class MyUI extends UI {
@Autowired
ItemService itemService
@Override
protected void init(VaadinRequest r) {
setContent(layout)
}
}
That is all, now you can run the application and ItemService will be autowired.
Step 5
Run the application grails run-app and open http://localhost:8080/spring-autowiring-basics
in a browser.
73
Application With Navigator
In this tutorial we will show how to initialize Navigator and how to implement View .
The first two steps are the same as for the previous 'Create Simple Application'.
Step 1
We need to say the plugin that we want to do annotation based URL mapping. Comment out
mapping from VaadinConfig.groovy to do that.
vaadin {
// mapping = [
// "/*": "app.MyUI"
// ]
}
Step 2
Now we will create a dummy service ItemService that we will autowire in Vaadin code.
package app
import grails.transaction.Transactional
@Transactional
class ItemService {
String serviceMethod() {
return 'Value from service'
}
}
Step 3
In this step we will do the following things:
74
Application With Navigator
After the point mentioned above are done, we can use Views class to open a view.
Continue to the next step to learn how views are registered using @VaadinUI annotation.
package app
import com.vaadin.grails.navigator.Views
import com.vaadin.grails.ui.DefaultUI
import com.vaadin.grails.ui.VaadinUI
import com.vaadin.server.VaadinRequest
@VaadinUI(path = '/')
class MyUI extends DefaultUI {
@Override
protected void init(VaadinRequest r) {
super.init(r)
Views.enter(ItemView)
}
}
Step 4
Before we use Views.enter(View) method we need to tell the pluging where are the views
and what is the URL path to them.
Add @VaadinUI annotation to every view that should be accesible by Views.enter method.
75
Application With Navigator
package app
import com.vaadin.grails.navigator.VaadinView
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
import org.springframework.beans.factory.annotation.Autowired
@VaadinView(path = "item")
class ItemView extends VerticalLayout implements View {
@Autowired
ItemService itemService
@Override
void enter(ViewChangeListener.ViewChangeEvent e) {
setMargin(true)
Step 5
Run the application grails run-app and open http://localhost:8080/spring-autowiring-
navigator in a browser.
76
UI
UI
This chapter shows how to do basic operations with Vaadin UI components in Grails.
77
Re-using GORM Validations
When we define validation rules, constraints, in domain class we probably do not want to
repeat that validation rules in Vaadin code. We would rather re-use it in Vaadin code for
validation of input fields.
We can get constraints from a domain class and use it. Because Vaadin provides many
validator, we can use them and fill it with what we have defined in constraints for a domain
class.
Assume we have a product, domain class, that has a name. The product name needs to
fulfil certiain validation rules. The name cannot be blank, it has too be more than 2
characters long and maximum lenght is 255.
class Product {
String name
static constraints = {
name(blank: false, minSize: 2, maxSize: 255)
}
}
Then we can get the constraints in Vaadin code and use it as parameters for validation.
78
Re-using GORM Validations
form.addComponent(txnName)
79
Async Push
Async Push
Example code is available on github.com/vaadin-on-grails/async-push.
Push has been added in Vaadin plugin version 7.3.0.1. Make sure you have this, or later,
version of the plugin.
Step 1
Enable anyc in VaadinConfig.groovy.
asyncSupported = true
Step 2
In order to demonstrate Vaadin push, we will create a view that will create a label that will
have initial value that will be overriden by a thread. The thread will wait one second and then
set other text into the label. Let's say, that we replace waiting by a call to external system,
where we expect a delay.
For pusing another label, we create Pusher thread that will change text of the label.
80
Async Push
package app.views.push
import app.MyUI
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
@Override
void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
loadingText.setSizeUndefined();
addComponent(loadingText);
new Pusher().start();
}
MyUI.current.access(new Runnable() {
@Override
public void run() {
loadingText.setValue("Done!")
}
});
}
}
}
Step 3
Add Push annotation on your UI class.
81
Async Push
package app
import app.views.push.PushView
import com.vaadin.annotations.Push
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
@Push
class MyUI extends UI {
@Override
protected void init(VaadinRequest vaadinRequest) {
navigator.navigateTo(PushView.VIEW_NAME)
}
}
82
Multiple application
Multiple UI application
Example code is available on github.com/vaadin-on-grails/multiple-ui-application.
In this article we will create two new UIs that we will show under different URLs.
Step 1
ClientUI will be available on http://localhost:8080/client.
package app
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
setContent(layout)
}
}
83
Multiple application
package app
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
setContent(layout)
}
}
Step 2
Open VaadinConfig.groovy and change the mapping, so the mapping points to the new UIs.
mapping = [
"/client/*": "app.ClientUI",
"/admin/*": "app.AdminUI"
]
Now we can start up the application and access both URLs to see each is mapped to
different UI class.
84
SASS Compilation
SASS Compilation
Example code is available on github.com/vaadin-on-grails/sass-compilation.
SASS compilation will happen automatically, during runtime, in all environments except of
production environment. This is handy, because we do not have to recompile SASS files
after each change.
Let's create an example theme that will extend new Valo theme provided by Vaadin 7.3.
Step 1
Create new folders /VAADIN/themes/mytheme in web-app . Then we create new SASS file
named styles.scss in web-app/VAADIN/themes/mytheme folder.
@import "../valo/valo";
.mytheme {
@include valo;
}
Step 2
Add the name of a theme to VaadinConfig.groovy , in our example mytheme .
We can also define Vaadin version for SASS compilation by defining sassCompile variable.
If we do not define Vaadin version a default version will be provided by Vaadin plugin.
vaadin {
themes = ['mytheme']
sassCompile = '7.3.0'
}
85
SASS Compilation
Then styles.scss gets compiled into styles.css when we run grails prod war
command.
This configuration is required for SASS compilation that is executed as part of grails
prod war command.
Step 3
The last step is to let Vaadin know what is the active theme. Add @Theme annotation with
name of our custom theme on our UI class.
package app
import com.vaadin.annotations.Theme
import com.vaadin.grails.Grails
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Button
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
@Theme("mytheme")
class MyUI extends UI {
@Override
protected void init(VaadinRequest r) {
setContent(layout)
}
}
Step 4
Run the app and notice the changed background and the button, which is using Valo theme.
When you add ?debug as a parameter into URL, you wil see what theme is used as
well as other debug logs.
86
SASS Compilation
87
Widgetset Compilation
Widgetset Compilation
Example code is available on github.com/vaadin-on-grails/widgetset-compilation.
This article shows how to recompile widgetset when we add an add-on that requires
widgetset recompilation.
We will demonstrate how to add tokenfield. But you can use this tutorial in the same way for
the other add-ons as well.
Step 1
Add the depedencies to add-ons in BuildConfig.groovy .
repositories {
inherits true
grailsPlugins()
grailsHome()
mavenLocal()
grailsCentral()
mavenCentral()
mavenRepo "http://maven.vaadin.com/vaadin-addons"
}
dependencies {
compile "org.vaadin.addons:tokenfield:7.0.1"
}
Step 2
Create src/java/app/widgetset.gwt.xml file with widgetset references.
<!DOCTYPE
module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0//EN"
"http://google-web-toolkit.googlecode.com/svn/releases/2.0/distro-source/core/src/
gwt-module.dtd">
<module>
<inherits name="org.vaadin.tokenfield.TokenfieldWidgetset"/>
</module>
88
Widgetset Compilation
If you want to add more add-ons, just add more lines with widget sets.
<module>
<inherits name="org.vaadin.tokenfield.TokenfieldWidgetset"/>
<inherits name="org.vaadin.otheraddon1.TheWidgetset"/>
<inherits name="org.vaadin.otheraddon2.TheWidgetset"/>
</module>
Step 3
Add the widgetset reference into VaadinConfig.groovy .
vaadin {
mapping = [
"/*": "app.MyUI"
]
productionMode = false
widgetset = 'app.widgetset'
}
environments {
production {
vaadin {
productionMode = true
}
}
}
We can try to run the application in order to see that the application will not come up. That
will show that widgetset compilation is mandatory.
Step 4
We will add a text field on UI. Use TokenField in order to finish this example.
89
Widgetset Compilation
package app
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import org.vaadin.tokenfield.TokenField
@Override
protected void init(VaadinRequest r) {
setContent(layout)
}
}
Step 5
Run grails vaadin-compile-widgetset --verbose to recompile the widgetset.
Step 6
After the widgetset compilation is done and you run the application, you will see the
tokenfield component in the browser.
90
Spring Security
Spring Security
Spring Security in pure Grails application, where no Vaadin is involved, is provided by
spring-security-core plugin, because if we work with pure Grails, the controllers are the end
points and we can define security at that level, by adding Spring security annotations. This is
not case for Vaadin application.
91
Spring Security Dependency
dependencies {
String springSecurityVersion = '3.2.5.RELEASE'
compile "org.springframework.security:spring-security-core:$springSecurityVersion"
, {
excludes 'aopalliance', 'aspectjrt', 'cglib-nodep', 'commons-collections', 'co
mmons-logging', 'ehcache', 'fest-assert', 'hsqldb', 'jcl-over-slf4j', 'jsr250-api', 'j
unit', 'logback-classic', 'mockito-core', 'powermock-api-mockito', 'powermock-api-supp
ort', 'powermock-core', 'powermock-module-junit4', 'powermock-module-junit4-common', '
powermock-reflect', 'spring-aop', 'spring-beans', 'spring-context', 'spring-core', 'sp
ring-expression', 'spring-jdbc', 'spring-test', 'spring-tx'
}
}
Follow the next chapters to learn how to setup Spring Security in your project.
92
Spring Security Basics
We will create basic classes that are required to work with Spring in Grails application.
The first step before you continue with this tutorial, is to enable OSIV, as described in Open
Session In View chapter to allow lazy loading in GORM. If you do not want OSIV in your
project, set lazy to false on roles collection in User class.
Step 1
Create Role domain class that will represent a role assigned to a user. For example, a user
can have multiple roles, like admin, client and so on.
package app.security
class Role {
String name
static constraints = {
}
}
Step 2
Create User domain class that will represent your user.
Then implement UserDetails interface from Spring Security and provide all the required
fields.
93
Spring Security Basics
package app.security
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
String username
String password
boolean accountNonExpired
boolean accountNonLocked
boolean credentialsNonExpired
boolean enabled
static constraints = {
}
@Override
Collection<? extends GrantedAuthority> getAuthorities() {
println roles
return roles.collect { Role authority ->
new SimpleGrantedAuthority(authority.name)
}
}
@Override
boolean isAccountNonExpired() {
return accountNonExpired
}
@Override
boolean isAccountNonLocked() {
return accountNonLocked
}
@Override
boolean isCredentialsNonExpired() {
return credentialsNonExpired
}
@Override
boolean isEnabled() {
return enabled
}
}
Step 3
94
Spring Security Basics
Because we need a user with some roles during development, create a new user with few
roles in BootStrap .
import app.security.Role
import app.security.User
class BootStrap {
Step 4
Now create UserService that will search for user by name and password in the database.
95
Spring Security Basics
package app.security
import grails.transaction.Transactional
@Transactional
class UserService {
Step 5
Create your implementation of AuthenticationManager interface in src/groovy that will
authentificate a user.
package app.security
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.AuthenticationException
import org.springframework.security.core.GrantedAuthority
@Autowired
private UserService userService
96
Spring Security Basics
import app.security.AuthManager
beans = {
authenticationManager(AuthManager)
}
Step 6
This can be done in many ways, but let's create a helper class Auth that will encapsulate
authentification.
package app.security
import com.vaadin.grails.Grails
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
class Auth {
SecurityContextHolder.context.authentication = result
return result
}
}
We do not have to have the login method defined as static. Instead, we can define a
new bean and autoinject or use Grails.get(Auth) where needed.
97
Secured Navigator
Secured Navigator
Example code is available on github.com/vaadin-on-grails/spring-security-basics.
In this article we will show way how to create Vaadin application with secured views, where a
view will be viewable by certain role.
Step 1
In ViewSecurity class we will store the mapping of a view to user roles. The class will be
also responsible to verify whether a view is accesible by a user.
98
Secured Navigator
package app.security
import com.vaadin.navigator.View
import org.springframework.security.authentication.InternalAuthenticationServiceExcept
ion
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
class ViewSecurity {
return false
}
}
Step 2
We need to hook at event when a view changes, so we can verify whether a user is able to
access a view.
99
Secured Navigator
package app.security
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
@Override
boolean beforeViewChange(ViewChangeListener.ViewChangeEvent event) {
View view = event.newView
boolean isViewAccessible = ViewSecurity.isViewAccessible(view)
return isViewAccessible
}
@Override
void afterViewChange(ViewChangeListener.ViewChangeEvent event) {
}
}
Step 3
Now we will create two views where one will be accesible only by "ADMIN" role.
package app.view.secured
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
@Override
void enter(ViewChangeListener.ViewChangeEvent event) {
setMargin(true)
package app.view.login
import app.security.Auth
import app.view.secured.UserDataView
100
Secured Navigator
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Button
import com.vaadin.ui.TextField
import com.vaadin.ui.VerticalLayout
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
@Override
void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
TextField txnUsername = new TextField("Username")
TextField txnPassword = new TextField("Password")
Button btnLogin = new Button("Login")
addComponent(txnUsername)
addComponent(txnPassword)
addComponent(btnLogin)
btnLogin.addClickListener(new Button.ClickListener() {
@Override
void buttonClick(Button.ClickEvent clickEvent) {
String username = txnUsername.value
String password = txnPassword.value
try {
Authentication auth = Auth.login(username, password)
} catch (BadCredentialsException e) {
// TODO: handle error flow
current.navigator.navigateTo(LoginView.VIEW_NAME)
}
}
})
}
}
101
Secured Navigator
Step 4
Now we will create UI class that will initialize Navigator and ViewSecurity .
package app
import app.security.SecuredViewChangeListener
import app.security.ViewSecurity
import app.view.login.LoginView
import app.view.secured.UserDataView
import com.vaadin.annotations.PreserveOnRefresh
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
@PreserveOnRefresh
class MyUI extends UI {
@Override
protected void init(VaadinRequest r) {
navigator.addView(LoginView.VIEW_NAME, LoginView)
navigator.addView(UserDataView.VIEW_NAME, UserDataView)
ViewSecurity.add(LoginView, null)
ViewSecurity.add(UserDataView, ['ADMIN'])
navigator.navigateTo(LoginView.VIEW_NAME)
setContent(layout)
}
}
Step 5
Run application grails run-app and fill in username and password.
102
Secured Navigator
Click on Login button and you will be authentificated and redirected to secured view.
103
Localization
Localization
This chapter shows way how to localize Vaadin application in Grails.
104
Localization Basics
Localization Basics
Example code is available on github.com/vaadin-on-grails/localization-basics.
In order to access the values in from the localized property files, use Grails.i18n()
method. Grails class is provided by the plugin. Here are various ways how to use i18n
method.
105
Custom MessageSource
Custom MessageSource
Example code is available on github.com/vaadin-on-grails/custom-messagesource.
We might want to define a custom MessageSource that will return a localized message. If a
message is missing, we might want to log information about missing localization (in logs or
database) or we might want to provide other way to fetch the localized labels.
Step 1
Enable OSIV in VaadinConfig.groovy . Add or comment out the following line.
openSessionInViewFilter = 'org.springframework.orm.hibernate4.support.OpenSessionInVie
wFilter'
Step 2
Create new domain object that will hold localization data. Run grails create-domain
app.Message command.
key holds the localization key that we will you in our application to refer a localized
string
value is localized string, for example a label in English
package app
class Message {
String key
String value
Locale locale
}
Step 3
Create localized key-value pair for given language in BootStrap.groovy .
106
Custom MessageSource
import app.Message
class BootStrap {
Step 4
Implement a new message source that will use GORM domain object, Message in our case,
to load the localized messages. When a value is not found, we will return the key in
brackets.
107
Custom MessageSource
package app.i18n
import app.Message
import org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSour
ce
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.support.AbstractMessageSource
import java.text.MessageFormat
@Autowired
PluginAwareResourceBundleMessageSource messageBundleMessageSource
@Override
protected MessageFormat resolveCode(String code, Locale l) {
Message message = Message.findByKeyAndLocale(code, l)
MessageFormat format
if (message) {
format = new MessageFormat(message.value, message.locale)
} else {
format = messageBundleMessageSource.resolveCode(code, l)
if (!format) {
format = new MessageFormat("[$code]", l)
}
}
return format
}
}
Step 4
Open grails-app/conf/spring/resources.groovy and add a new bean messageSource and
messageBundleMessageSource that we use to get the localization in case the localization is not
found in database.
108
Custom MessageSource
import app.i18n.JdbcMessageSource
import org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSour
ce
beans = {
messageSource(JdbcMessageSource)
messageBundleMessageSource(PluginAwareResourceBundleMessageSource) {
basenames = "WEB-INF/grails-app/i18n/messages"
}
}
Step 5
Now we can use standard Grails.i18 method to get localized strings.
package app
import com.vaadin.grails.Grails
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
@Override
protected void init(VaadinRequest r) {
setContent(layout)
}
}
Step 6
Run the application grails run-app and open it in the browser http://localhost:8080/custom-
messagesource. Then we will see the messages in the console.
109
Custom MessageSource
110
REST
REST
This chapter will show way how to add REST API to the same project where a Vaadin
application running.
111
Without using root URL
If you need to provide REST API from your application and you do not want to provide that
from other application, there is a way how to do it from Grails even if we run there Vaadin
applications.
First thing if you want to have REST API, do not map any Vaadin UI on /* (root) url. If you
have to use the root, check the next article "Using root URL for Vaadin app".
Step 1
Your mapping should like like this.
mapping = [
"/admin/*": "app.AdminUI",
"/client/*": "app.ClientUI"
]
Step 2
Then, we can add URL mapping into UrlMappings.groovy .
class UrlMappings {
static mappings = {
group "/rest", {
"/$controller/$action?/$id?"()
}
}
}
Step 3
Create a controller grails create-controller app.ItemController and implement some logic
there. For example, fetch some data from database and return it as JSON. In our example,
we will just return a map, with dummy data, as JSON.
112
Without using root URL
package app
import grails.converters.JSON
class ItemController {
def index() {
Map data = ['some': 'data']
Step 4
Create two sample Vaadin UIs, so we can verify URL mapping.
package app
import com.vaadin.grails.ui.DefaultUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
setContent(layout)
}
}
113
Without using root URL
package app
import com.vaadin.grails.ui.DefaultUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
setContent(layout)
}
}
Step 5
Start up the application and try out different URLs:
http://localhost:8080/rest-without-root/client
http://localhost:8080/rest-without-root/admin
http://localhost:8080/rest-without-root/rest/item/index
114
Using root URL for Vaadin app
URL mapping can be done also in way we use / root URL to display Vaadin application. In
this article, we are going to show how to do it.
Step 1
Create mapping in UrlMapping.groovy as follows:
class UrlMappings {
static mappings = {
"/" {
controller = "redirect"
}
// add your URL mapping for controllers
group "/rest", {
"/$controller/$action?/$id?"()
}
}
}
Step 2
Then we need to create the controller that will redirect the request to the Vaadin application.
package app
class RedirectController {
def index() {
redirect(uri: "/app")
}
}
Step 3
Last step is to make sure that VaadinConfig.groovy contains mapping to Vaadin UI class.
115
Using root URL for Vaadin app
vaadin {
mapping = [
"/app/*": "app.MyUI"
]
}
Step 4
Create a controller and implement some logic there. For example, fetch some data from
database and return it as JSON.
package app
class RedirectController {
def index() {
redirect(uri: "/app")
}
}
Step 5
Create two sample Vaadin UI, so we can verify URL mapping.
package app
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.grails.Grails
@Override
protected void init(VaadinRequest r) {
setContent(layout)
}
}
116
Using root URL for Vaadin app
Step 6
Start up the application and try out these URLs:
117
Plugin development
Plugin development
This chapter describes the way you can influence Grails plugin, for example, update Vaadin
version or add more support for Grails or Vaadin.
We will explore how Grails plugin for Vaadin is developed, maintained and also how to add
an enhancement.
118
Github
Github
Vaadin plugin source codes are publicly shared on Github.
First you need to fork and clone the following grails-vaadin-plugin repository.
After you have commited and pushed your changes, which will be described in Development
section, create a pull request back to original Github repository.
When the pull request is merged the authors of the plugin will create a new version.
119
Development
Development
Create a sample Grails application with Vaadin plugin that you will use for plugin
development.
There are two ways to use the plugin in the sample application.
Way 1
Add direct dependency to BuildConfig.groovy. You can add it as the last row there.
grails.plugin.location.'vaadin' = "/Users/john/projects/grails-vaadin7-plugin"
Then all the changes do in Vaadin plugin will become immediatelly available in the sample
application.
Way 2
The second way is to release plugin into local maven repository. Before you do so, you need
to set plugin version to SNAPSHOT.
Then you reference SNAPSHOT version in the sample application. You can do the changes
in Vaadin plugin and release it as a snapshot to your local maven repository.
grails maven-install
120