8

如果可能,我想将 GWTRequestFactory用于所有客户端-服务器通信。我的理解是,您必须映射/gwtServletRequestFactoryServlet您的web.xml,然后使用@Service注释来告诉RequestFactoryServlet如何将客户端请求映射到其相应的服务。

有人可以在客户端和服务器端提供此过程的完整代码示例吗?我想将一个Widget对象从客户端发送到WidgetProcessor服务器端的服务:

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);
        }
    }
}

在非 GWT 上下文中,我只需定义 a WidgetProcessorServlet,将其映射到/processWidget,并使其看起来像:

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
    WidgetProcessor widgetProcessor = new WidgetProcessor();
    widgetProcessor.processWidget(getWidgetFromRequest(request));
}

RequestFactory这在-land中如何工作?提前致谢。

4

5 回答 5

4

可以使用 RequestFactories,但也可以使用 GWT-RPC。我更喜欢 RequestFactories。

您将拥有以下类和接口:

在服务器上:

  1. 小部件(Servlet)
  2. 小部件处理器

在客户端:

  1. 小部件代理
  2. 小部件请求
  3. WidgetRequestFactory
  4. WidgetPresenter

小部件Servlet

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));
    }
}

小部件处理器

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);
        }
    }
}

小部件代理

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
}

小部件请求

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...
            }
        });
    }
}

另外:如果您再次向用户响应已处理的小部件,您将使其如下所示:

@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.

    }
}
于 2013-02-20T16:50:06.277 回答
4

您对 RequestFactory 场景有些困惑。

您需要从这里开始 - https://developers.google.com/web-toolkit/doc/latest/DevGuideRequestFactory

浏览示例 RequestFactory 演示 @ DynatableRF 代码 - http://code.google.com/p/google-web-toolkit/source/browse/#svn/trunk/samples/dynatablerf

下载示例 RequestFactory 演示 @ DynatableRF 代码 - http://google-web-toolkit.googlecode.com/files/gwt-2.5.0.zip

编辑 - RequestFactory 示例与 MVP、活动和编辑器框架复杂。需要付出大量努力才能确定您的场景需要哪种 RF、编辑器、MVP 和 Activties 组合。

于 2013-02-18T15:34:27.297 回答
3

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

于 2013-02-24T10:09:14.263 回答
1

您的 Widget 类将在服务器端。在客户端,您将使用一个接口来表示一个 Widget;此接口将成为实际 Widget 对象的代理。您可以使用 @ProxyFor 注释将代理接口与类相关联。例如,如果你在服务器上有 Widget 类,你可以在客户端有 WidgetProxy 接口:

@ProxyFor(value = Widget.class)
public interface WidgetProxy extends EntityProxy {
}

代理包含实体属性的 getter 和 setter,这些 getter 和 setter 镜像在服务器上的类中。请求工厂还需要一种方法来定位与代理关联的类,为此我使用“定位器”类(尽管还有其他方法)。定位器也在 @Proxy 注释中指定:

@ProxyFor(value = Widget.class, locator = WidgetLocator.class)

WidgetLocator 类也在服务器端。对于您要插入或更新的每个小部件,您都需要创建一个 RequestContext。RequestContext 标识将对实体进行操作的方法。这些方法的实际实现再次在服务器端......您可以引入一个包含这些方法的单独类,或者将它们添加到实体类(在您的情况下为 Widget)。我更喜欢将它们分成一个“DAO”类,将实体类(即Widget)限制为一个简单的bean。(您的 DAO 类名为 WidgetProcessor)。客户端的RequestContext是一个扩展RequestContext接口的接口。您的 RequestContext 接口告诉请求工厂在哪里可以找到服务器上的 DAO,这就是您使用 @Service 注释的地方。

查看 Thomas Broyer 的博客以获得很好的介绍: GWT 2.1.1 RequestFactory。我还发现 GWT in Action (Second Edition) 一书是一个有用的资源。我根据我的学习经验创建了一个示例,它可能对您也有用:A GWT Request Factory Journey;同样,这可能有用也可能没用!

于 2013-02-20T13:49:10.997 回答
1

我刚刚为您的目的开发了一个简单的骨架项目。在 Github 上查看我的答案小部件处理器

该项目基于 Maven 构建器和 Java EE 平台 (GlassFish)。

项目模块:

  1. ear- 通用耳模块将其他模块集成在一个易于部署的 EAR 包中;
  2. persistence- 该模块只有一个文件persistence.xml,并将所有外部实体链接到一个数据源;
  3. ejb- 该模块具有实体Widget和无状态 EJB WidgetProcessor
  4. web- 带有 RequestFactory 的通用 GWT 模块。

调整 Maven 构建过程以正确构建所有内容。该项目可以毫无问题地导入 IntelliJ Idea。并且可以使用标准的 Idea 工具在 Glassfish 中进行调试。

此外,我已将 GWT RF 和 Persistence 样板代码移至Github上的外部bilionix-core工件。

于 2013-02-25T10:42:49.777 回答