Page tree
Skip to end of metadata
Go to start of metadata

About this Tutorial

This tutorial will show you how to create master/detail screens with GWT. The list (master) screen will have the ability to sort columns, as well as page 25 records on the server at a time. The form (detail) screen will use an responsive CSS form layout (courtesy of Bootstrap). You will also configure client and server-side validation to improve your users' experience.

IntelliJ IDEA Rocks

We highly recommend using IntelliJ IDEA when developing web applications in Java. Not only is its Java and JUnit support fantastic, but it has excellent CSS and JavaScript support. Using JRebel with IDEA is likely to provide you with the most pleasant Java development experiences you've ever had.
This tutorial assumes you've created a project with the appfuse-basic-gwt archetype and have already completed the Persistence and Services tutorials. If you're using the appfuse-modular-gwt archetype, please morph your mind into using the web module as the root directory. If you created your project with a different web framework than GWT, you're likely to be confused and nothing will work in this tutorial. (wink)

Table of Contents


Source Code


The code for this tutorial is located in the "tutorial-gwt" module of the appfuse-demos project on GitHub. Use the following command to check it out from Subversion:

svn co

Extend Persistence/Service Layers

Add methods to your PersonManager for Remote Pagination

We will add a couple of methods to PersonManager for server side remote pagination. This tutorial asumes you have followed the Persistence and Services tutorials so you can add these methods to your existing PersonManager and PersonManagerImpl classes:

Annotate your Person POJO for Validation

You can annotate your POJO entities with javax.validation annotations that GWT RequestFactory framework will automatically pick up for validating your entities before trying to persist them: javax.validation Annotations

Implement GWT RequestFactory data oriented Remote Services

We will be using GWT RequestFactory data oriented services for communication between server and client. You can find more information about RequestFactory here:

PersonLocator bean

Create a in src/main/java/**/webapp/server/locators. This component will instruct RequestFactory about how to perform CRUD operations on the Person entity.

PersonProxy interface

Create a interface in src/main/java/**/webapp/client/proxies. PersonProxy interface is the client-side representation of a server-side Person entity, using @ProxyFor annotation to configure server side  mapped Entity and the Locator to find CRUD operations for that entity:

PersonRequest interface for remote service

Create the interface in src/main/java/**/webapp/client/requests, This interface should match the PersonManager method you would like to expose to remote clients:


Now add a PersonRequest entry to src/main/java/**/webapp/client/requests/ (fragment)

I18n keys/values for Literal Externalization

GWT uses a generated java interface to access externalized literals so we will be adding those literals beforehand so we can use those methods in our view objects without compilation errors.

Open src/main/resources/**/webapp/client/application/ and add i18n keys/values for the various "person" properties: (fragment)


Use mvn gwt:i18n command to re-generate methods for your newly added "person" properties.

Warning, this command will overwrite src/main/java/**/webapp/client/application/ so it's always a good idea to have a backup, or even better, to check you code into source control.

Search/List Person functionality

AppFuse follows GWT Model-View-Presenter(MVP) pattern, where the View interface is a central part of the pattern, gluing together Views and Activities:

  • exposes view properties via getters/setters
  • holds the Delegate interface which includes those methods that this view needs to delegate to its Presenter (Activity).

PersonSearchView interface

Create a in src/main/java/**/webapp/client/ui/people/list extending ProxySearchView:


ProxySearchView already contains methods that most search/list views would need. You don't need to create this interface. Generic Interface


To implement PeopleSearchActivity we will be extending AbstractProxySearchActivity that require the following methods to be implemented:


Create a in src/main/java/**/webapp/client/ui/people/list extending AbstractProxySearchActivity:

This example implements local client-side sorting, but also includes hints to implement remote server-side sorting. and PeopleSearchViewImpl.ui.xml

Now create the view implementation ( and its associated template (PeopleSearchViewImpl.ui.xml) files in src/main/java/**/webapp/client/ui/people/list:

The most interesting part of this file is the method createTableColumns() where you can define and customize data to show in the listing table.



Configure Search/List View

To make this functionality available to the application you need to add the following configuration:

  • Add the activity to the ApplicationActivityMapper
  • Bind together View and View Implementation for ioc view injection
  • Add a new menu entry for 'View People'


Open src/main/java/**/webapp/client/ui/client/application/ and add your activity to the getActivity(..) method:

Configure View Injection: ClientGinModule

Open src/main/java/*/webapp/client/ui/client/application/ioc/ and bind togheter View and View Implementation inside configure() method (fragment)


Open src/main/java/**/webapp/client/ui/client/application/ to add a new menu entry: (fragment)

Edit Person (Form Detail)

EditPersonView interface

Create an in src/main/java/**/webapp/client/ui/people/edit extending ProxyEditView:


ProxyEditView already contains methods that most edit views would need. You don't need to create this interface.

ProxyEditView .java (fragment)


To implement PeopleSearchActivity we will be extending AbstractProxySearchActivity that require the following methods to be implemented:

Required methods are:

  • createProxyRequest()
  • loadProxyRequest(RequestContext, EntityProxyId)
  • saveOrUpdateRequest(RequestContext, EntityProxy)
  • deleteRequest(RequestContext, EntityProxy)


  • createProxy(RequestContext): instantiate a new Proxy for adding
  • getProxyClass(): determine Proxy class (which is lost at runtime), useful for reusing the same Activity with different Proxy subclases
  • loadProxyRequest(RequestContext, EntityProxyId): create a Request to load a persistent object
  • getSavedMessage(): customizes success messages
  • getDeletedMessage(): customizes success messages
  • nextPlace(boolean): customizes navigation
  • previousPlace(): customizes navigation

Create a in src/main/java/**/webapp/client/ui/people/edit extending AbstractProxyEditActivity: and EditPersonViewImpl.ui.xml

Create and EditPersonViewImpl.ui.xml in src/main/java/**/webapp/client/ui/people/edit

Configure EditPerson view


Open src/main/java/**/webapp/client/ui/client/application/ and add your activity to the getActivity(..) method: (fragment)

IOC View Injection: ClientGinModule

Open src/main/java/**/webapp/client/ui/client/application/ioc/ and bind togheter View and View implementation inside configure() method (fragment)

Annotate your PersonManager interface for security and access control

Project comes configured to honor Spring Security Access Control @PreAuthorize, @PostAuthorize and @Secured annotations so you can annotate your PersonManager interface for access control and security. (security annotations)


You can also enable ''(jsr250) annotations or configure other security strategies editing src/main/webapp/WEB-INF/security.xml


Using jetty:run

Configuring jetty

Compiling gwt 'inplace'

  • No labels