Last week, I posted a first article on GWT 2.1.1 RequestFactory, followed a few days later by one on GWT 2.1 Editors (and, as promised in the former, how to use them with RequestFactory). In this article, I'll deal with 3 topics I also promised to tackle: what changed since 2.1.0, how does RequestFactory compares to GWT-RPC, and finally how does it integrates with JSR-303 Bean Validation (feel free to jump directly your section of interest). But first, let's start with something I forgot to talk about in my previous article!
When you're asked to retrieve a domain object from your datastore, you should use at most one instance of a given persisted object (e.g. if you're asked twice for the Person with identifier 1, you should return the same instance each time, or at least instances that live in the same context so that changes to one instance will be persisted when saving another instance representing the same entity). This is causing many incomprehensions. Fortunately, when using JPA or JDO, it's as easy as using a request-scoped transaction.
What's new in 2.1.1
RequestFactory saw its first stable release in GWT 2.1.0. In GWT 2.1.1, the server part was totally rewritten, and the client side was slightly reworked as well. But this is all transparent to the developer, and code that compiled and ran with GWT 2.1.0 should still work with GWT 2.1.1. The following will probably only be useful for people who started using RequestFactory in 2.1.0 and want to know which new things can benefit them.
Features GWT 2.1.1 provides are summed up in the release announcement:
- "A service layer, which includes support for non-static service objects": GWT 2.1.1 introduced the
ServiceLocatorinterfaces, which allow you to, respectively, get rid of the
findXxxstatic method on entities (along with providing ID and version without necessarily using thus-named domain object properties), and instantiate a service class to be able to use instance methods for services.
- "EntityProxy are no longer the only type of proxies you can use on the client-side": GWT 2.1.1 adds the
ValueProxyinterface (and the
BaseProxyinterface that's a common parent for both
- "Multiple methods calls on a single request": in GWT 2.1.0 you could only have a single invocation on a give
fire()it. This limitation has simply been removed.
How does RequestFactory compare to GWT-RPC
The drawback is of course that there's a bit of redundancy (having to re-declare methods on the client-side interface), but on the other hand it brings flexibility and, if you ask me, removing the "must be translatable" constraint is enough to justify it.
It's worth mentionning that the dichotomy actually already existed in GWT-RPC in the service interfaces (synchronous, implemented by your
RemoteServiceServlet, and asynchronous, used on the client-side).
Despite removing the "must be translatable" constraint, RequestFactory comes with a number of limitations regarding the types that can be transported: only primitive types and their boxed classes, enums, strings, dates (
BigDecimal, other proxies, and finally
java.util.Set of any of the above, can be used. RequestFactory doesn't (yet!) support polymorphism (which means you have to use the exact classes I listed above; you cannot for instance declare a property of type
However, because of those limitations, RequestFactory does not use serialization policies computed at compile-time, which means that your client and server code are much more loosely coupled than with GWT-RPC. With RequestFactory, provided the changes were made in a compatible way, you can independently deploy your client and server code, including using DevMode in
-noserver mode against an already deployed application.
Actually, RequestFactory has all the advantages of De-RPC:
- the protocol is JSON-based, which makes deserialization very fast on the browser.
- client and server can use slightly different (but compatible) objects and still communicate (this was probably inspired by Protocol Buffers), which helps with hot-deployment.
- you don't have to compile and deploy your app each time you change a service or domain object to be able to debug using DevMode in the
…and it works on Google AppEngine.
Finally, although the API and concepts are highly different, RequestFactory and its new (in 2.1.1) support for
ValueProxy makes it possible to use it as a general-purpose RPC mechanism, at least to aid in migrating from GWT-RPC, and it's expected that De-RPC will die in favor of RequestFactory (don't worry, GWT-RPC will still be supported, we're only talking here about De-RPC, which never leaved the experimental state).
JSR-303 Bean Validation
When receiving a request to process, the
RequestFactoryServlet applies the operations on the domain objects and validates them before processing any invocation. The default behavior for that validation is to use
javax.validation, and that's why you might see an "
Unable to initialize a JSR 303 Bean Validator" error in your server logs if you do not have a JSR 303 implementation (such as Hibernate Validator) in your classpath, and why you must have the validation API in your classpath for RequestFactory to work, to begin with.
ConstraintViolations are reported on the client side as a set of
Violations to the
onViolation() method of
Receivers. Because validation is done before invocations are processed, all
Receivers for a given
RequestContext will receive the violations, and the default implementation of
onViolation() is to call
onFailure() with a fatal
ServerFailure, which will by result in a
In the next article, I expect to write about the
ServiceLayerDecorators, that is, the internals of the
RequestFactoryServlet, where you can plug your own code to tweak a few things.