Organized by Marakana, San Francisco Java User Group hosted an event on April 13th, 2010 with Kunal Jaggi who talked about integrating GWT with Spring and Hibernate ORM. So, in addition to the standard Spring+Hibernate integration (transactions, exception handling, DAO templates, etc.) Kunal also discussed how to access spring beans via GWT's RPC facilities. He talked about client side remote interfaces and service proxies, exception handling, domain object serialization to GWT, etc. Kunal demonstrated how all this fits together with a demo app he has prepared. http://www.sfjava.org/calendar/12296574/
2. Entity Inheritance
Agenda
Strategies
• Introduction to RPC
• Demo Application
• Persistence
• Validation
• Service Layer Impl with Spring 2.5
• Unit testing- Junit 4 parameterized testing
• Build and Deployment
• Q&A
www.javaevangelist.com
3. Entity Inheritance
Scope of this talk
Strategies
• More of a hands-on tutorial, rather than a
presentation.
• GWT backend communication option- RPC
• UI framework- GWT
No Spring MVC
www.javaevangelist.com
4. Entity Inheritance
Why prefer RPC over Servlets?
Strategies
• Avoid writing any boilerplate code.
Pass any argument
Return any result from the server
• The client need not make synchronous HTTP
requests
www.javaevangelist.com
5. Entity Inheritance
GWT RPC Mechanism
Strategies
• RPC- fetching data from the server.
• Client-side JavaScript code needs to fetch data
from the server backend.
• Based on Java Servlets.
• Serialized objects are shared across the client
and server over HTTP.
• GWT RPC calls are asynchronous to make UI
more responsive.
www.javaevangelist.com
6. Entity Inheritance
GWT RPC Mechanism
Strategies
GWT UI Servlets
• GWT RPC is a mechanism for passing Java
objects to and from a server over standard
HTTP
www.javaevangelist.com
11. Entity Inheritance
The Remote Interface
Strategies
• The remote service interface is a pivotal element for
integration.
• Code Snippet
@RemoteServiceRelativePath("stocks/stockPriceServic
e")
public interface StockPriceService extends
RemoteService {
//abstract methods
}
The relative path defined by the remote service interface
is the key to identify the Spring managed bean to be
invoked
www.javaevangelist.com
17. Entity Inheritance
Test the DAO Implementation
Strategies
• We’ll use Spring custom runner to avoid
extending from framework classes.
• Code Snippet
StockPriceDAOTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/applicationContext-test.xml" })
public class StockPriceDAOTest {
…
www.javaevangelist.com
19. Entity Inheritance
Object Serialization
Strategies
• Methods parameters and return types should
be serializable.
• A user defined type is serializable if it’s
assignable to IsSerializable or Serializable.
www.javaevangelist.com
21. Entity Inheritance
Implementing Business Logic with Spring
Strategies
• Code Snippet
@Service("stockPriceService")
public class StockPriceServiceImpl implements
StockPriceService
• The business service is no longer managed by
the GWT RemoteServiceServlet.
www.javaevangelist.com
22. Entity Inheritance
Demarcating Transactions
Strategies
• Spring framework delegates the responsibility
of transaction manager to an underlying
implementation.
• Since we’re using Hibernate, we’ll roll in a
HibernateTransactionManager to take care of
transaction management.
www.javaevangelist.com
24. Entity Inheritance
Overriding Transaction Behavior
Strategies
• Since Write operations are not allowed in read-
only mode, we must override the transaction
behavior for the saveupdate and delete
operations.
• Code Snippet
@Transactional(readOnly = false)
public boolean saveOrUpdate(StockPrice
stock)throws StockValidationExcepion {
www.javaevangelist.com
26. Entity Inheritance
Implementing Validations
Strategies
• Client-side validation: in the addStock()
method we alert the user if she tries to add a
stock symbol which is not a number, letter or
dots; for example, a special character.
• Server-side validation: we propagate a
DelistedException when the user tries to add a
delisted stock symbol. For the sake of
simplicity, a checked DelistedException is
thrown when the stock symbol “ERR” is added.
www.javaevangelist.com
27. Entity Inheritance
Introducing Hibernate Validator
Strategies
• Reference Implementation (RI) of JSR 303-
bean validation, simplifies domain validation by
providing a cross tier validation support.
• It’s not tied to any particular tier, you can
validate your domain classes just from
anywhere- web, business services or even
before domain objects are inserted into a
relational table from the data access layer.
www.javaevangelist.com
28. Entity Inheritance
Annotating POJOs for Validations
Strategies
• Code Snippet
StockPrice.java
public class StockPrice implements Serializable {
@Pattern(regexp="[0-9a-zA-Z.]{1,10}$",
message="Stock code must be between 1 and
10 chars that are numbers, letters, or dots.")
@CheckDelistedStock
private String symbol;
www.javaevangelist.com
30. Entity Inheritance
Unit Testing the Validation Implementation
Strategies
• We’ll leverage from JUnit4 parameterized test
cases.
www.javaevangelist.com
33. Entity Inheritance
Plumbing Spring Services into GWT
Strategies
• We’ll use Spring4GWT, an open source library
for integrating GWT modules with Spring
managed back-end.
www.javaevangelist.com
34. Entity Inheritance
GWT RPC with Spring
Strategies
• Step 1 – Define synchronous interface which
extends from RemoteService interface.
• Step 2 – Define Spring-based service
implementation class which implements the
synchronous interface (created in step 1).
• Step 3 – Configure web.xml for Spring4GWT
www.javaevangelist.com
35. Entity Inheritance
GWT RPC with Spring (contd.)
Strategies
• Step 4 – Define asynchronous interface. Follow
the naming pattern- <sync_interface>Async.
• Step 5 – Create service proxy at the client-side
• Step 6 – Define client-side callbacks to handle
success/failures.
www.javaevangelist.com
36. Entity Inheritance
Step 1- Hooking GWT Modules with Spring
Strategies
• The remote service interface is a pivotal element for
integration.
• Code Snippet
@RemoteServiceRelativePath("stocks/stockPriceServic
e")
public interface StockPriceService extends
RemoteService {
//abstract methods
}
The relative path defined by the remote service interface
is the key to identify the Spring managed bean to be
invoked
www.javaevangelist.com
37. Entity Inheritance
Step 2 - Spring Service Implementation
Strategies
• The Service Implementation class is a pure
Spring bean without any dependency on the
GWT RPC RemoteServiceServlet.
• Code Snippet
StockPriceServiceImpl.java
@Service("stockPriceService")
@Transactional(readOnly = true)
public class StockPriceServiceImpl implements
StockPriceService {
//dependencies
www.javaevangelist.com
39. Entity Inheritance
Step 4 - Write an asynchronous interface
Strategies
• Guidelines
Same name as the service interface, appended
with Async
Each method must have the same name and
signature as in the service interface with an
important difference: the method has no return
type and the last parameter is an
AsyncCallback object.
www.javaevangelist.com
40. Entity Inheritance
Step 5 - Instantiate the Service Proxy
Strategies
• Create an instance of the service proxy class by
calling GWT.create(Class)
• There’s noting new at the front-end. The remote
service is called in the usual way using the
GWT.create() method.
• Code Snippet
private StockPriceServiceAsync stockPriceSvc =
GWT.create(StockPriceService.class);
www.javaevangelist.com
41. Entity Inheritance
Step 5 - Write callback methods
Strategies
• Specify a callback method which executes
when the call completes.
• The AsyncCallback object contains two
methods, one of which is called depending on
whether the call failed or succeeded:
onFailure(Throwable) and onSuccess(T).
www.javaevangelist.com
42. Entity Inheritance
Defining Asynchronous Interface
Strategies
interface MyServiceAsync {
public void myMethod(String s, AsyncCallback<String>
callback);
}
pass in a callback object
No return type that can be notified when
an asynchronous call
completes
www.javaevangelist.com
43. Entity Inheritance
Why asynchronous calls?
Strategies
• All GWT-based server calls execute
immediately.
• GWT RPC calls are non-blocking.
• Improves user experience
UI remains responsive
A client can do multitask
Can call several server methods in parallel
www.javaevangelist.com