3

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

我在使用 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-interface”通过页面连接的客户端,它是一个简单地向路径发出 GET、POST 请求的客户端在服务器上(从其他地方)。这个远程客户端根本没有“使用”GWT。客户端通过 HttpServlet 进行连接,在这个 servlet 内部我想重用 RPC 机制,这样我就不必重写位于客户端并使用客户端相关代码的接口(实现已经是服务器端)。

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

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

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

谢谢!

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

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

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,甚至没有实现它。这就是我在服务器端想要的,所以我不必使用线程或为“异步使用”创建新的实现。对不起,如果我不清楚!

4

2 回答 2

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() {
        ...
    }
}

然后,传输实现使用这个业务逻辑类,只添加特定于传输的东西(例如注释):

总重量:

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

因此,传输端点只是真正功能的外壳,在一个地方实现,即 class MyBusinessLogic

于 2013-11-06T12:48:58.803 回答
0

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

无论如何,您可以创建一个新的 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();
   }
}
于 2013-11-06T14:33:09.500 回答