GWT使用RequestFactory命中HTTP servlet

时间:2013-02-18 11:42:49

标签: java gwt servlets requestfactory

如果可能,我想将GWT的RequestFactory用于所有客户端 - 服务器通信。我的理解是,您必须在/gwtServlet中将RequestFactoryServlet映射到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环境中,我只需定义WidgetProcessorServlet,将其映射到/processWidget,并使其看起来像:

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

这如何在RequestFactory - 土地上运作?提前谢谢。

5 个答案:

答案 0 :(得分:4)

你对RequestFactory场景感到有点困惑。

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

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

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

修改 RequestFactory示例使用MVP,活动和编辑器框架进行复杂化。需要付出大量的努力才能得出RF,编辑,MVP和放大器的哪种组合。您的方案需要的活动。

答案 1 :(得分:4)

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

您将拥有以下类和接口:

在服务器上:

  1. 小工具(Servlet)
  2. WidgetProcessor
  3. 在客户端:

    1. WidgetProxy
    2. WidgetRequest
    3. WidgetRequestFactory
    4. WidgetPresenter
    5. 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: 如果您再次向用户回复已处理的小部件,您可以这样做:

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

答案 2 :(得分:3)

我认为没有必要为此目的使用Request Factory进行脑力激荡。

根据我的观点 Gwt RPC可以非常简单。

简而言之,简单的RPC结构如下:

GWT Code <===> InterfaceAsync <===> Interface (Synchronous)<===> Server Code 

我试图用你自己的元素来解释。

同步接口(整个RPC的核心):

import com.google.gwt.user.client.rpc.RemoteService;
public interface WidgetRPCInterface extends RemoteService
{
    public Widget widgetProcessRPC(Widget myWidget);
}

ASynchronous接口(客户端的关键部分):

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface WidgetRPCInterfaceAsync
{
    public void widgetProcessRPCWidget myWidget, AsyncCallback callback);
}

您可以使用 Service(等于servlet)来实现“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 
}

在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>

最后在您的GWT代码中。使用以下服务

在代码中使用

//注册服务。

   private final WidgetRPCInterfaceAsync widgetService = 
        GWT.create(WidgetRPCInterface.class);
        ServiceDefTarget endpoint = (ServiceDefTarget) service;
        endpoint.setServiceEntryPoint('widgetrpc');

使用回调请求服务器

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。软件包结构:

WidgetRPCInterfaceAsync,WidgetRPCInterface 应该在client * package中

小部件类应该在共享*包

WidgetRPCImpl 应该在server * package

并查看RPC示例

答案 3 :(得分: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类也在服务器端。对于要插入或更新的每个Widget,您需要创建一个RequestContext。 RequestContext标识将对该实体进行操作的方法。这些方法的实际实现再次在服务器端...您可以引入一个包含方法的单独类,或者将它们添加到实体类(在您的情况下为Widget)。我更喜欢将它们分成“DAO”类,将实体类(即Widget)限制为一个简单的bean。 (您的DAO类名为WidgetProcessor)。客户端上的RequestContext是扩展RequestContext接口的接口。您的RequestContext接口告诉请求工厂在服务器上找到DAO的位置,以及您使用@Service注释的位置。

请看看Thomas Broyer的博客,以获得一个很好的介绍:GWT 2.1.1 RequestFactory。我还发现GWT in Action(第二版)这本书是一本有用的资源。我根据自己的学习经验创建了一个示例,这对您也很有用:A GWT Request Factory Journey;再次,这可能有用也可能没用!

答案 4 :(得分:1)

我刚刚为您的目的开发了一个简单的骨架项目。 检查我的回答widget-processor on Github

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

项目模块:

  1. ear - 普通耳模块将其他模块整合到一个易于部署的EAR包中;
  2. persistence - 此模块只有一个文件persistence.xml,并将所有外部实体链接到一个数据源;
  3. ejb - 此模块包含实体Widget和无状态EJB WidgetProcessor;
  4. web - 带有RequestFactory的常规GWT模块。
  5. Maven构建过程已调整为正确构建所有内容。该项目可以毫无问题地导入IntelliJ Idea。它可以使用标准的Idea工具在Glassfish中进行调试。

    此外,我已将GWT RF和持久性样板代码移至external bilionix-core artifacts on Github