Java 为非实体请求实现GWT RequestFactory服务

Java 为非实体请求实现GWT RequestFactory服务,java,gwt,requestfactory,server-communication,Java,Gwt,Requestfactory,Server Communication,我有以下Java servlet,它执行我所称的“添加服务”: 我正试图让GWT的RequestFactory使用ValueProxy和AdditionService做同样的事情(在应用服务器上添加两个数字并返回总和作为响应),但遇到了一些问题 下面是AdditionRequest(客户端层),它是一个值对象,包含两个要添加的整数: // Please note the "tier" (client, shared, server) I have placed all of my Java cl

我有以下Java servlet,它执行我所称的“添加服务”:

我正试图让GWT的RequestFactory使用
ValueProxy
AdditionService
做同样的事情(在应用服务器上添加两个数字并返回总和作为响应),但遇到了一些问题

下面是
AdditionRequest
(客户端层),它是一个值对象,包含两个要添加的整数:

// Please note the "tier" (client, shared, server) I have placed all of my Java classes in
// as you read through the code.
public class com.myapp.client.AdditionRequest {
    private Integer addend;
    private Integer augend;

    public AdditionRequest() {
        super();

        this.addend = 0;
        this.augend = 0;
    }

    // Getters & setters for addend/augend.
}
下一个我的代理(客户端层):

下一个我的服务API(在共享层中):

最后,奇迹发生的地方(服务器层):

public类com.myapp.server.DefaultAdditionService实现AdditionService{
@凌驾
公共请求总额(添加请求){
整数和=request.getAddend()+request.getAugend();
回报金额;
}
//因为AdditionService扩展了RequestContext,所以还有一堆
//GWT迫使我在这里实现:append、create、isChanged等等。
//我真的需要实现所有这些吗?
}
以下是我的问题:

  • 我的“分层”策略正确吗?我是否已将所有类型打包到正确的客户端/共享/服务器包中?
    • 我认为我的设置不正确,因为
      AdditionService
      (在共享中)引用了服务器上的
      DefaultAdditionService
      ,它不应该这样做。共享类型应该能够同时存在于客户端和服务器上,但不依赖于任何一个
  • ServiceProvider
    应该是实现
    RequestFactory
    的类,还是应该是扩展它的接口?如果是后者,我在哪里定义
    ServiceProvider
    impl,如何将其链接回所有其他类
  • 那么
    ServiceProvider
    DefaultAdditionService
    中的所有这些方法呢?我是否需要实现这些核心GWT方法中的所有20多个?或者我使用API的方式不正确,或者没有尽可能简单地使用它
  • 服务定位器在这里的作用是什么?怎么做

  • 如果您想将RF用作一种简单的RPC机制[*],您可以(而且您是对的:仅
    ValueProxy
    s),但您需要更多的东西:
    ServiceLocator
    s(即GWT 2.1.1)

    使用
    ServiceLocator
    可以简单地将服务实现(如servlet)放入真实的服务实例,而不是实体对象(因为您将只使用
    ValueProxy
    s,不使用RF协议所要求的静态
    getXyz()
    方法)。请注意,还存在
    Locator
    s,用于从服务器端实体外部化所有这些方法:如果到处使用
    ValueProxy
    ,则不需要

    ServiceLocator
    看起来像(取自):

    您的服务将是地球上最简单的事情(无需扩展/实施任何与射频相关的内容):

    如果您错误地说出了
    sum()
    ,或者没有实现在
    RequestContext
    中声明的方法,您将得到一个错误

    要实例化
    RequestContext
    s,您需要使用
    com.myapp.shared.AdditionService
    的公共工厂方法扩展
    RequestFactory
    接口。比如:

    @Service(value = DefaultAdditionService.class, locator = DefaultAdditionServiceLocator.class)
    public interface com.myapp.shared.AdditionService extends RequestContext {
      // Note here, you need to use the proxy type of your AdditionRequest.
      Request<Integer> sum(AdditionRequestProxy request);
    }
    
    public interface AdditionServiceRequestFactory extends RequestFactory {
      public com.myapp.shared.AdditionService createAdditionServiceRequestContext();
    }
    
    你所有的客户电话都将从这里开始。如果还没有,请参阅文档

    现在,RF的工作原理是将要传递的对象从客户端(使用
    EntityProxy
    ValueProxy
    )和服务器(真实对象,或者
    Entity
    值,或者简单的
    DTO
    类)完全分离。您将在客户机/共享层中的任何位置使用代理类型(即自动生成实现的接口),并且仅在服务器端使用相对域对象(用
    @ProxyFor
    引用的对象)。剩下的就交给RF了。因此,您的
    AdditionRequest
    将位于服务器端,而
    AdditionRequestProxy
    将位于客户端(请参阅
    RequestContext
    中的说明)。还要注意的是,如果您只是使用基本类型/装箱类型作为
    RequestContext
    params或返回类型,您甚至不需要创建
    ValueProxy
    s,因为它们是默认的

    您需要的最后一点是在
    web.xml
    上连接
    RequestFactoryServlet
    。请看这里的图片。请注意,如果您想使用自定义的
    ExceptionHandler
    s或
    servicelayercorator
    s,您可以扩展它,但不需要这样做

    说到把所有东西放在哪里:

    • Locator
      s、
      ServiceLocator
      s、服务实例、域对象和
      RequestFactoryServlet
      扩展将位于服务器端
    • RequestContext
      RequestFactory
      扩展和您的所有代理类型都将位于共享端
    • 客户端将初始化
      RequestFactory
      扩展,并使用它获取服务请求的工厂实例
    总而言之。。。要使用RF创建简单的RPC机制,只需:

    • 使用
      ServiceLocator
      创建您的服务
    • 为您的请求创建一个
      RequestContext
      (用服务和定位器值注释)
    • 创建一个
      RequestFactory
      扩展来返回您的
      RequestContext
    • 如果您想在
      RequestContext
      中使用多个基本类型(如simple
      DTO
      s),只需为它们创建客户端代理接口,用
      @ProxyFor
      注释,并记住在何处使用每种类型
    • 把所有东西都装上电线
    很像那样。好吧,我写得太多了,可能忘了什么:)

    有关参考,请参阅:

    • )
    • 托马斯·布罗耶的文章
    • 从作者的角度
      @Service(value=DefaultAdditionService.class)
      public interface com.myapp.shared.AdditionService extends RequestContext {
          Request<Integer> sum(AdditionRequest request);
      }
      
      public class com.myapp.shared.ServiceProvider implements RequestFactory {
          public AdditionService getAdditionService() {
              return new DefaultAdditionService();
          }
      
          // ... but since I'm implementing RequestFactory, there's about a dozen
          // other methods GWT is forcing me to implement: find, getEventBus, fire, etc.
          // Do I really need to implement all these?
      }
      
      public class com.myapp.server.DefaultAdditionService implements AdditionService {
          @Override
          public Request<Integer> sum(AdditionRequest request) {
              Integer sum = request.getAddend() + request.getAugend();
              return sum;
          }
      
          // And because AdditionService extends RequestContext there's another bunch of
          // methods GWT is forcing me to implement here: append, create, isChanged, etc.
          // Do I really need to implement all these?
      }
      
      public class DefaultAdditionServiceLocator implements ServiceLocator {
        @Override
        public Object getInstance(Class<?> clazz) {
          try {
            return clazz.newInstance();
          } catch (InstantiationException e) {
            throw new RuntimeException(e);
          } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
          }
        }
      }
      
      @Service(value = DefaultAdditionService.class, locator = DefaultAdditionServiceLocator.class)
      public interface com.myapp.shared.AdditionService extends RequestContext {
        // Note here, you need to use the proxy type of your AdditionRequest.
        Request<Integer> sum(AdditionRequestProxy request);
      }
      
      public class com.myapp.server.DefaultAdditionService {
        // The server-side AdditionRequest type.
        public Integer sum(AdditionRequest request) {
          Integer sum = request.getAddend() + request.getAugend();
          return sum;
        }
      }
      
      public interface AdditionServiceRequestFactory extends RequestFactory {
        public com.myapp.shared.AdditionService createAdditionServiceRequestContext();
      }