GWT:在服务器端调用与客户端相同的RPC方法

这个问题可能看似愚蠢/琐碎,但我根本无法理解如何实现我的目标。 (对不起,如果标题是误导,想不到更好的一个)

我在App Engine服务器上有一个使用GWT的网页。 我得到了客户端代码和服务器代码。 客户端代码可以毫无问题地调用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 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,但我不知道是否可能(如果是,请告诉我如何)!

谢谢!

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

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

 MyClassServiceAsync = (MyClassServiceAsync) GWT.create(MyClassService.class); ServiceDefTarget serviceDef = (ServiceDefTarget) service; serviceDef.setServiceEntryPoint(GWT.getModuleBaseURL() + "myService"); service.doSomething(new AsyncCallback() { @Override public void onSuccess(Void result) { //do something when we know server has finished doing stuff } @Override public void onFailure(Throwable caught) { } }); 

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

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

一个示例,概念validation设置:检查与Firebug的网络通信,以了解正在发生的事情。 然后尝试用curl调用服务。

2)如果您不想使用GWT方言,则可以轻松地公开与REST(JSON)或Web服务(SOAP)相同的服务。 有很多库,例如REST案例RestEasy和Jersey 。 你没有提到任何服务器端框架(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(); } } 

因此,传输端点只是实际function的shell,在一个地方实现,即MyBusinessLogic类。

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

无论如何,你可以创建一个新的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(); } }