【问题标题】:GWT: invoke the same RPC-methods on the server-side as on the client-sideGWT:在服务器端调用与客户端相同的 RPC 方法
【发布时间】:2013-11-17 15:10:13
【问题描述】:

这个问题可能看起来愚蠢/微不足道,但我根本无法理解如何实现我的目标。 (对不起,如果标题误导,想不出更好的)

我在使用 GWT 的 App Engine 服务器上有一个网页。我得到了客户端代码和服务器代码。客户端代码可以毫无问题地调用 RPC 方法(我的问题与“gwt-client”完全无关)。

我有以下课程:

//MyClassService.java - client package
@RemoteServiceRelativePath("myService")
public interface MyClassService extends RemoteService{
   public doSomething();
}

//MyClassServiceAsync.java - client package
public interface MyClassServiceAsync{
   public void doSomething(AsyncCallback<Void> callback);
}

//MyClassServiceImpl.java - server package
public class MyClassServiceImpl extends RemoteServiceServlet implements MyClassService{
   @Override
   public void doSomething()
   {
      //does something
   }
}

一个场景和我想做的事情: 我有一个远程客户端,换句话说,一个没有通过“GWT 接口”通过页面连接的客户端,它只是一个客户端,它只是向服务器上的路径(从其他地方)发出 GET、POST 请求。这个远程客户端根本没有“使用”GWT。客户端通过 HttpServlet 进行连接,在这个 servlet 内部我想重用 RPC 机制,这样我就不必重写位于客户端并使用客户端相关代码的接口(实现已经是服务器端)。

要重用服务器端的现有方法,我可以创建 MyClassServiceImpl.java 的一个实例并直接使用它们。但是正如您在上面看到的,它们是作为同步方法实现的,因为 GWT-RPC 在使用 GWT-RPC 时会自动使调用异步。

我将如何在服务器端重用 MyClassServiceImpl 并将它们作为异步的?

另外,如果我对所采用的方法有误,请提出其他解决方案。例如,一种解决方案可能是远程客户端直接与 RemoteServiceServlet 通信,而不是创建客户端通过其连接的 HttpServlet,但我不知道这是否可能(如果可能,请告诉我如何)!

谢谢!

编辑(感谢下面的一些答案,我得到了一些见解,并将尝试改进我的问题):

方法的服务器端实现是同步的。这意味着他们将阻塞直到返回结果。从 gwt-client 代码调用这些方法时,它们会“自动”变为异步,可以通过执行以下操作来调用它们:

MyClassServiceAsync = (MyClassServiceAsync) GWT.create(MyClassService.class);
ServiceDefTarget serviceDef = (ServiceDefTarget) service;
serviceDef.setServiceEntryPoint(GWT.getModuleBaseURL() + "myService");

service.doSomething(new AsyncCallback<Void>() {
 @Override
 public void onSuccess(Void result) {
   //do something when we know server has finished doing stuff
 }

 @Override
 public void onFailure(Throwable caught) {
 }
});

从上面的代码可以看出,doSomething 方法支持 AsyncCallback,甚至没有实现它。这就是我在服务器端想要的,所以我不必使用线程或为“异步使用”创建新的实现。对不起,如果我不清楚!

【问题讨论】:

  • HTTP 协议基于请求-响应原则。所以本质上每个请求都是“阻塞的”——客户端打开一个连接,发送请求,等待回复,然后服务器关闭连接。请注意,服务器是多线程的,可以同时处理多个请求(= 创建并行线程并并行调用 servlet 方法),因此几乎不需要在服务器端进行异步处理。你真正想解决什么问题?
  • 请注意,您必须通过启用并发请求在 GAE 上显式启用多线程:developers.google.com/appengine/docs/java/config/…
  • 感谢您的意见!这更像是一个“保持代码干净”的问题,然后是一个实际的问题。正如您在问题的编辑部分中看到的那样。我真正追求的是尽可能保持服务器和客户端上的代码相同,因此我不必在服务器上为该方法的 AsyncCallback 版本创建实现。当我真正指的是方法的 AsyncCallback 版本时,我可能太快使用“异步”这个词。

标签: java google-app-engine gwt servlets


【解决方案1】:

1) 任何客户端都可以使用当前配置调用MyClassServiceImpl.doSomething()MyClassServiceImpl 是一个 servlet 并已正确公开。为了以这种方式实现通信,客户端必须能够“说”GWT 方言以进行数据传输。 Google 可能会为您提供实现此功能的库。我没用过,所以无法提出建议。

一个示例,概念验证设置:检查与 Firebug 的网络通信,以了解发生了什么。然后尝试使用curl 调用服务。

2) 如果您不想使用 GWT 方言,您可以轻松地公开与 REST (JSON) 或 Web 服务 (SOAP) 相同的服务。有很多图书馆,例如对于 REST 案例 RestEasyJersey。你没有提到任何服务器端框架(Spring?Guice?CDI?),所以这个例子会很简单。

我建议在一个独立于运输方法的类中实现您的业务方法:

public class MyBusinessLogic {
    public void doSomething() {
        ...
    }
}

然后,传输实现使用此业务逻辑类,仅添加特定于传输的内容(例如注释):

GWT:

public class MyClassServiceImpl extends RemoteServiceServlet implements MyClassService{
    @Override
    public void doSomething() {
        MyBusinessLogic bean = ... // get it from IoC, new, whatever
        bean.doSomething();
    }
}

JAX-RS:

@Path("myService")
public class MyResource {
    @GET
    public void doSomething() {
        MyBusinessLogic bean = ... // get it from IoC, new, whatever
        bean.doSomething();
    }
}

所以传输端点只是真正功能的外壳,在一个地方实现,类@9​​87654329@。

【讨论】:

  • 感谢您对使用一些 REST 实现的回答和建议!根据 GWT-RPC 的工作方式,我的逻辑已经分开。我希望有一个解决方案可以“自动”使我的服务器端方法在 gwt-client 调用它们时像它们一样异步,但正如 Peter Knego 在他的评论中指出的那样,这只是客户端的“魔法”,即我可能无法在服务器端使用。我会尝试更新我的问题,以更好地反映我所追求的,以便我仍然可以获得更好的解决方案。
【解决方案2】:

这是一个真实的例子吗?您的方法不接受任何参数,也不返回任何数据。

无论如何,您都可以创建一个新的 servlet 并通过正常的 HTTP 请求调用它。然后 servlet 只调用目标方法:

public class MyNewServlet extends HttpServlet{
    protected void doGet(HttpServletRequest request, HttpServletResponse response){
       MyBusinessLogic bean = ... // get it from IoC, new, whatever
       bean.doSomething();
   }
}

【讨论】:

  • 不确定我是否不清楚,但我想我在写以下内容时已经很清楚了:“要在服务器端重用现有方法,我可以创建一个 MyClassServiceImpl.java 的实例,然后使用那些。但是正如你在上面看到的,它们是作为同步方法实现的,因为 GWT-RPC 在使用 GWT-RPC 时会自动使调用异步。 - 之后我问我如何让它们像 gwt-client 调用它们时那样异步。
  • 抱歉,代码错误 - 已编辑。实际上你会直接调用业务逻辑。
  • 方法在客户端是异步的:当 RPC 调用正在进行时,javascript 代码可以继续执行,然后当 RPC 响应可用时,调用提供的回调。这是必需的,因为 JS 在单线程中。所有这些都与服务器端无关——只是一个普通的 HTTP servlet 请求。
  • 所以,基本上,除非我明确地为它们创建一个实现,否则我无法实现方法的“异步”调用(在服务器端)?
猜你喜欢
  • 2014-04-08
  • 2016-06-28
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
相关资源
最近更新 更多