Reputation:
I want to use GWT's RequestFactory
for all client-server communication, if possible. My understanding is that you have to map /gwtServlet
to RequestFactoryServlet
in your web.xml
, and then use @Service
annotations to tell the RequestFactoryServlet
how to map client-side requests to their appropriate services.
Can someone provide a complete code example of this process, both on the client- and on the server-side? I'd like to send a Widget
object from the client side to a WidgetProcessor
service on the server-side:
public class Widget {
// This is a domain object (POJO).
}
public class WidgetProcessor {
public void processWidget(Widget w) {
// Inspect the Widget. If certain properties contain certain
// values, place it on a queue. Else "process" the Widget
// and persist it to a DB.
if(w.containsSpecialValues())
QueueManager.sendToQueue(w);
else {
// Process widget...
WidgetDAO.save(w);
}
}
}
In a non-GWT context, I would just define a WidgetProcessorServlet
, map it to /processWidget
, and make it look like:
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
WidgetProcessor widgetProcessor = new WidgetProcessor();
widgetProcessor.processWidget(getWidgetFromRequest(request));
}
How does this work in RequestFactory
-land? Thanks in advance.
Upvotes: 8
Views: 1889
Reputation: 3269
I've just developed a simple skeleton project for your purpose. Check my answer widget-processor on Github.
The project is based on Maven builder and the Java EE platform (GlassFish).
Project modules:
ear
- common ear module incorporates others in one EAR package which is easy to deploy;persistence
- this module has only one file persistence.xml
and links all external entities to one data source;ejb
- this module has entity Widget
and stateless EJB WidgetProcessor
;web
- general GWT module with RequestFactory.Maven build process tuned to build everything properly. The project could be imported into IntelliJ Idea without any problems. And it could be debugged in Glassfish using standard Idea tools.
Also I have moved GWT RF and Persistence boilerplate code to external bilionix-core
artifacts on Github.
Upvotes: 1
Reputation: 2747
Its possible with RequestFactories but its also possible with GWT-RPC. I prefer RequestFactories.
You will have a following classes and interfaces:
on server:
on client:
WidgetServlet
package com.foo.bar.server;
public class Widget {
//Your methods
public void yourInstanceMethod(){
//foo
}
public static void yourStaticMethod(){
//bar
}
public static void processWidget(Widget w){
WidgetProcessor widgetProcessor = new WidgetProcessor();
widgetProcessor.processWidget(getWidgetFromRequest(request));
}
}
WidgetProcessor
package com.foo.bar.server;
public class WidgetProcessor {
public void processWidget(Widget w) {
// Inspect the Widget. If certain properties contain certain
// values, place it on a queue. Else "process" the Widget
// and persist it to a DB.
if(w.containsSpecialValues())
QueueManager.sendToQueue(w);
else {
// Process widget...
WidgetDAO.save(w);
}
}
}
WidgetProxy
package com.foo.bar.server;
import com.foo.bar.server.Widget;
@ProxyFor(value = Widget.class)
public interface WidgetProxy extends EntityProxy{
//Your getter and Setter methods
}
WidgetRequest
package com.foo.bar.client;
import com.foo.bar.server.Widget;
@Service(value = Widget.class)
public interface WidgetRequest extends RequestContext{
InstanceRequest<WidgetProxy, Void> yourInstanceMethod();
Request<Void> yourStaticMethod();
Request<Void> widgetProcessor(WidgetProxy widget);
}
WidgetRequestFactory
package com.foo.bar.client;
public interface WidgetRequestFactory extends RequestFactory{
WidgetRequest widgetRequest();
}
WidgetPresenter
package com.foo.bar.client;
public class WidgetPresenter {
private final WidgetRequestFactory rf = GWT.create(WidgetRequestFactory.class);
public WidgetPresenter() {
rf.initialize(new EventBus());
rf.widgetRequest().widgetProcessor().fire(new Receiver<Void>() {
@Override
public void onSuccess() {
//Do what you want to confirm to user...
}
});
}
}
Addtionally: If you responde the processed widget again to the User you would make it like this:
@Service(value = Widget.class)
public interface WidgetRequest extends RequestContext{
...
Request<WidgetProxy> widgetProcessor(WidgetProxy widget);
}
public class Widget {
...
public static void processWidget(Widget w){
WidgetProcessor widgetProcessor = new WidgetProcessor();
return widgetProcessor.processWidget(getWidgetFromRequest(request));
}
}
public class WidgetProcessor {
public Widget processWidget(Widget w) {
// Inspect the Widget. If certain properties contain certain
// values, place it on a queue. Else "process" the Widget
// and persist it to a DB.
if(w.containsSpecialValues())
QueueManager.sendToQueue(w);
else {
// Process widget...
WidgetDAO.save(w);
}
return w;
}
}
public class WidgetPresenter {
private final WidgetRequestFactory rf = GWT.create(WidgetRequestFactory.class);
public WidgetPresenter() {
rf.initialize(new EventBus());
rf.widgetRequest().widgetProcessor().fire(new Receiver<WidgetProxy>() {
@Override
public void onSuccess(WidgetProxy response) {
WidgetView v = new WidgedView(response);
RootPanel.get().add(view);
}
});
}
}
package com.foo.bar.client;
public class WidgetView {
public WidgetView(WidgetProxy widget) {
//paint widget with widget
// widget.getSomeProperty(); etc.
}
}
Upvotes: 4
Reputation: 121998
I think no need to do Brain Storming with Request Factory
for this purpose.
It can be very simple With Gwt RPC
as per my opinion .
In short the simple RPC structure as below :
GWT Code <===> InterfaceAsync <===> Interface (Synchronous)<===> Server Code
I am trying to explain with you elements it self .
The Synchronous Interface(central to the whole RPC):
import com.google.gwt.user.client.rpc.RemoteService;
public interface WidgetRPCInterface extends RemoteService
{
public Widget widgetProcessRPC(Widget myWidget);
}
The ASynchronous Interface(Key part on Client):
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface WidgetRPCInterfaceAsync
{
public void widgetProcessRPCWidget myWidget, AsyncCallback callback);
}
Here you go with the Service
(Equals to servlet) which implements "WidgetRPCInterface"
public class WidgetRPCImpl extends RemoteServiceServlet implements RPCInterface
{
private static final long serialVersionUID = 1L;
public Widget widgetProcessRPCWidget myWidget)
{
//Process your widget here (CRUD operations)
//You can change return type and return what ever you want to client .
}
**you can override doget,doPost,doDelete....etc along with your methods
}
Map the above class in your web.xml;
<servlet>
<servlet-name>widgetrpc</servlet-name>
<servlet-class>com.server.WidgetRPCImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>widgetrpc</servlet-name>
<url-pattern>/widgetrpc</url-pattern>
</servlet-mapping>
Finally in your GWT Code .Use service as below
Using in Code:
//register the service .
private final WidgetRPCInterfaceAsync widgetService =
GWT.create(WidgetRPCInterface.class);
ServiceDefTarget endpoint = (ServiceDefTarget) service;
endpoint.setServiceEntryPoint('widgetrpc');
requesting server with callback
widgetService.widgetProcessRPC(widgetFromClient, callback);
AsyncCallback callback = new AsyncCallback()
{
public void onFailure(Throwable caught)
{
//Do on fail
}
public void onSuccess(Object result)
{
//Process successfully done with result (result is which you
returned in impl class) .
}
};
P.S .Beware of package structures:
WidgetRPCInterfaceAsync ,WidgetRPCInterface should be in client* package
Widget class should be in shared* package
WidgetRPCImpl should be in server* package
And Have a look on RPC Example
Upvotes: 3
Reputation: 9537
You are a bit confused about RequestFactory scenarios.
You need to start here - https://developers.google.com/web-toolkit/doc/latest/DevGuideRequestFactory
Browse Sample RequestFactory demo @ DynatableRF code - http://code.google.com/p/google-web-toolkit/source/browse/#svn/trunk/samples/dynatablerf
Download Sample RequestFactory demo @ DynatableRF code - http://google-web-toolkit.googlecode.com/files/gwt-2.5.0.zip
Edit - RequestFactory examples get convoluted with MVP, Activities and Editor Framework. A great deal of effort would be required to conclude which combination of RF, Editor, MVP & Activties you would need with your scenarios.
Upvotes: 4
Reputation: 1662
Your Widget class will be on the server-side. On the client-side you will use an interface to represent a Widget; this interface will be a proxy for the actual Widget object. You associate the proxy interface with the class using the @ProxyFor annotation. For example, if you have the Widget class on the server, you could have the WidgetProxy interface on the client:
@ProxyFor(value = Widget.class)
public interface WidgetProxy extends EntityProxy {
}
The proxy contains getters and setters for the properties of the entity, and those getters and setters are mirrored in the class on the server. Request factory also needs a way to locate the class that the proxy is associated with, and I use a "locator" class for this (although there are other approaches). The locator is also specified in the @Proxy annotation:
@ProxyFor(value = Widget.class, locator = WidgetLocator.class)
The WidgetLocator class is also on the server side. For each Widget that you want to insert or update you will need to create a RequestContext. The RequestContext identifies the methods that will operate against the entity. The actual implementation of those methods is again on the server side ... you can either introduce a separate class containing the methods, or add them to the entity class (Widget in your case). I prefer to separate them into a "DAO" class, limiting the entity class (i.e., Widget) to a simple bean. (Your DAO class is named WidgetProcessor). The RequestContext on the client side is an interface that extends the RequestContext interface. Your RequestContext interface tells request factory where to find the DAO on the server, and that's where you use the @Service annotation.
Take a look at Thomas Broyer's blog for a good introduction: GWT 2.1.1 RequestFactory. I also found the book GWT in Action (Second Edition) a useful resource. I created an example based upon my learning experience, which may also be useful to you: A GWT Request Factory Journey; again, this may or may not be useful!
Upvotes: 1