GWT:在服务器端调用与客户端相同的RPC方法 [英] GWT: invoke the same RPC-methods on the server-side as on the client-side

查看:129
本文介绍了GWT:在服务器端调用与客户端相同的RPC方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我在使用GWT的App Engine服务器上有一个网页。我得到了客户端代码和服务器代码。客户端代码可以调用RPC方法,没有任何问题(我的问题根本就没有用于完成gwt-client的任何操作)。



我得到了以下类:

$ $ p $ // MyClassService.java - 客户端程序包
@RemoteServiceRelativePath(myService)
public interface MyClassService扩展RemoteService {
public doSomething();
}

//MyClassServiceAsync.java - 客户端程序包
public interface MyClassServiceAsync {
public void doSomething(AsyncCallback< Void> callback);


//MyClassServiceImpl.java - 服务器包
public class MyClassServiceImpl extends RemoteServiceServlet implements MyClassService {
@Override
public void doSomething()
{
//做某事
}
}

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

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



我会如何去在服务器端重用MyClassServiceImpl并将它们设置为异步?



另外,如果我错误地使用了我的方法,请提供其他解决方案。例如,一种解决方案可能是让远程客户端直接与RemoteServiceServlet进行通信,而不是创建客户端连接的HttpServlet,但我不知道这是否可能(如果是,请告诉我如何)!



谢谢!

编辑并会尝试改进我的问题):

这些方法的服务器端实现是SYNCHRONOUS。意思是他们会阻止,直到结果返回。当从gwt-client代码调用这些方法时,它们被自动地做成异步的,可以通过执行以下操作来调用它们:

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

service.doSomething(new AsyncCallback< Void>(){
@Override
public void onSuccess(Void result){
//当我们知道服务器时做某事已完成做

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

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

解决方案

<1>任何客户端都可以调用 MyClassServiceImpl.doSomething() code>与当前配置。 MyClassServiceImpl 是一个servlet并正确公开。为了以这种方式实现沟通,客户必须能够说出数据传输的GWT方言。 Google可能会为您提供实现此功能的库。我没有用过任何东西,所以我不能提出建议。



一个示例,概念证明设置:检查与Firebug的网络通信以了解正在进行。然后尝试用 curl 来调用服务。


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



我建议在一个服务器端实现你的业务方法类独立于传输方法:

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

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

GWT:

 <$ c $ MyClassServiceImpl扩展RemoteServiceServlet实现MyClassService {
@Override
public void doSomething(){
MyBusinessLogic bean = ... //从IoC获取它,new,
bean.doSomething();


JAX-RS:

  @Path(myService)
public class MyResource {
@GET
public void doSomething(){
MyBusinessLogic bean = ... //从IoC获取它,new,
bean.doSomething();






$ b因此,传输端点只是实际功能的外壳,在一个地方实现,类 MyBusinessLogic


The question might seem stupid/trivial and might be, but I simply cannot understand how to achieve my goal. (Sorry if the title is misguiding, couldn't think of a better one)

I have a webpage on a App Engine server which uses GWT. I got client code and server code. The client code can call RPC methods without any problem (my problem has nothing to do with the "gwt-client" at all).

I got the following classes:

//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
   }
}

A scenario and what I want to do: I've got a remote client, in other words, a client who's not connecting through the page via the "GWT-interface", it's a client who's simply making GET, POST requests to a path on the server (from elsewhere). This remote client is not "using" GWT at all. The client is connecting through an HttpServlet, inside this servlet I want to reuse the RPC mechanics so that i don't have to rewrite the interfaces, who are on the client side and using client-dependent code (the implementation is already server-side).

To reuse the existing methods on the server-side I could create an instance of MyClassServiceImpl.java and just use those. BUT as you can see above, they are implemented as synchronous methods, since GWT-RPC automatically makes the calls asyncronous when using the GWT-RPC.

How would i go about to reuse the MyClassServiceImpl on the server-side and also get them as asynchronous?

Also if I'm wrong with the approach I'm taking, please suggest some other solution. For example, one solution might be for the remote client to directly communicate with the RemoteServiceServlet instead of creating a HttpServlet which the client connects through, but I don't know if that's possible (and if it is, please tell me how)!

Thank you!

EDIT (thanks to some answers below I got some insight and will try to improve my question):

The server-side implementation of the methods is SYNCHRONOUS. Meaning they will block until results a returned. When invoking these method from the gwt-client code, they are 'automatically' made ASYNCHRONOUS one can call them by doing the following:

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

As you can see from the above code, there is support for the doSomething method to take an AsyncCallback, without even having the implementation for it. This is what I wanted on the server-side so i didn't have to use threads or create a new implementation for "async-usage". Sorry if I was unclear!

解决方案

1) Any client can call MyClassServiceImpl.doSomething() with the current configuration. MyClassServiceImpl is a servlet and properly exposed. In order to achieve communication this way, the client must be able to "speak" the GWT dialect for data transportation. Google may provide you with libraries implementing this. I haven't used any, so I cannot make suggestions.

An example, proof-of-concept setup: Check the network communications with Firebug to get an idea of what is going on. Then try calling the service with curl.

2) If you do not want to use the GWT dialect, you can easily expose the same service as REST (JSON) or web services (SOAP). There are plenty of libraries, e.g. for the REST case RestEasy and Jersey. You do not mention any server-side frameworks (Spring? Guice? CDI?), so the example will be simplistic.

I'd suggest implementing your business method in a class independent of transportation method:

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

Then, the transport implementations use this business logic class, adding only transport-specific stuff (e.g. annotations):

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

So the transport endpoints are just shells for the real functionality, implemented in one place, the class MyBusinessLogic.

这篇关于GWT:在服务器端调用与客户端相同的RPC方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆