GWT RPC 调用在编译模式下不起作用

Posted

技术标签:

【中文标题】GWT RPC 调用在编译模式下不起作用【英文标题】:GWT RPC call not working in compiled mode 【发布时间】:2013-02-05 09:21:22 【问题描述】:

我正在构建一个 GWT 应用程序。以前,每当我从网页请求图像时,该请求都会发送到客户端类,该类用于提供图像。这适用于 GWT 生成的 URL 以及编译后的独立文件 URL。

但是现在我已经用对服务器的 Ajax (RPC) 调用替换了该部分,其中服务器端类从客户端类接收必要的参数,并提供由客户端类发送的图像到用户界面。这适用于 GWT 生成 URL,但编译后,当我尝试将其作为独立 html 运行时(通过在 URL 栏中提供文件的路径),不会触发任何 Ajax 请求。

是因为 RPC 调用需要服务器来响应(与 jQuery Ajax 调用相比,后者仅在桌面上运行良好)?如何在桌面模式下模仿 Ajax 行为?调用看起来像这样:

private final GreetingServiceAsync response = GWT.create(GreetingService.class); //(I haven't changed the defualt names..:))
response.greetServer(i, j,new AsyncCallback<String,String>()   // i,j is already calculated, server needs to know these to pass an image url
     public void onSuccess(String url1, String url2) ...
     public void onFailure(Throwable caught) ...
);

【问题讨论】:

很高兴看到..如果您发布完整的 rpc 调用... 桌面模式是什么意思? 我的意思是,找到文件的路径(名为foo.html 的那个,在war 目录中,foo.java 是调用'onModuleLoad 的类),然后输入它在 URL 栏中,例如 C://Users/Cupidvogel/Desktop/Workspace/foo/war/foo.html... 你想从 impl 类中引入路径并在客户端显示它们吗?? 我没听懂你。你能详细说明一下吗? 【参考方案1】:

你完全脱离了GWT structure

编译项目后,所有 GWT 代码都会转换为 javascript

即使没有服务器正在运行,并且如果您从 C://myapp/myapp.html 等文件系统访问了您的 html 文件。浏览器会将其用作静态网络

page ..ofcourse 在那个 html 页面里面会有你的 app.nochahe.js 这是纯 javascript 。

所以浏览器会毫不犹豫地显示所有内容..但它永远不会成为所谓的网络应用程序,它永远不会制作任何 ajax 或任何其他服务器

打电话。

在您的情况下,您没有运行任何服务器并将它们作为static pages 访问并期望它们连接server 并带来您的数据,这是完全不可能的。

所以首先请在开发模式下运行||调试你的代码。

开始运行或调试项目后..在开发模式选项卡中生成的url将如下所示。

h t t p : / / localhost : 8888 / MyModule.html ? gwt.codesvr = localhost : 9997

您可能对参数gwt.codesvr有疑问。

它运行您的客户端 Java 代码,该代码被编译为类文件,但尚未编译为 JavaScript 文件。

一旦完成你的实现,编译项目并将你的war文件夹导出到任何服务器上以测试或访问它们

ex:localhost:8080/myapp/someservice.

来到所谓的AJAX调用,它们是GWT中的RPC。RPC是GWT与服务器通信的内部结构,通常它们都是impl类,它们扩展了提供数据的RemoteServiceServlet到HTTP 协议上的客户端,并且在不运行服务器的情况下不可能唤起它们。

如果您仍然对不同的GWT 应用程序模式感到困惑,请参阅此差异link

【讨论】:

【参考方案2】:

您的意思是直接从文件系统打开 HTML 主机页面?这是行不通的,因为那时您还没有服务器。这样就没有服务器端可以应答您的 RPC 调用。您必须在 servlet 容器(如 Tomcat 或 Jetty)中运行您的 GWT 应用程序,以便服务器端 RPC servlet 正在运行并准备好响应来自客户端的 RPC 调用。

即使您在某处运行服务器。如果只是从文件系统中打开文件,RPC 调用无法在哪里找到服务器。 RPC 调用使用 URL(主机页面基本 URL)来定位其服务器。在您的情况下,这是 file://C/something 而不是 http://www.hererunsaserver.com/

您可以将数据嵌入应用程序中,以实现某种桌面模式。但是不知道你是不是这样的?

【讨论】:

谢谢阿德里安。是的,我也怀疑如果没有服务器,RPC 将无法工作。但是,我如何将页面提供给客户?在 GWT 生成的 URL 模式下,页面非常不稳定,每个clickhandler,或者动画需要数年才能完成。但是在桌面模式下,一切都和普通的 JS 一样流畅。当然,我不能将那个 URL 提供给客户,对吧,他会有可怕的 UI 体验吗?那么客户端如何像访问普通 HTML-JS 生成的页面一样舒适地访问服务器中的那个页面呢? 我不太明白您为什么要在服务器上创建图像 URL。您是在动态创建图像吗?如果没有,只需将图像放在与您的主机页面(或某些子文件夹)相同的文件夹中,然后计算客户端上的 URL。 GWT.getModuleBaseURL 应该可以帮助您创建图像 URL。如果服务器做了一些重要的事情,而您确实需要服务器,那么除了将您的应用程序部署到测试服务器并向您的客户发送该服务器的 URL 之外别无他法。 是的,当我在我的桌面上测试 GWT 应用程序作为 GWT 生成的代码时(没有编译,因此当你关闭服务器时页面将显示 Disconnected 模式对话框),页面非常不稳定,每个事件都需要大量时间来触发,无论是在菜单上简单的dropdown 调用,还是在单击元素后弹出警报。但是,当我编译相同的代码并通过其文件 URL 在浏览器中查看页面时,它的行为通常就像使用 HTML-CSS-JS 构建的页面一样。那么如果客户端通过 GWT 生成的 URL 访问页面,是否会持续出现断断续续的情况? 我假设您在所谓的GWT Development Mode 中从您的 IDE 运行应用程序。开发模式很慢,它会做各种事情来让您在 IDE 中工作时进行调试和重新加载。一旦你编译了你的应用并deploy它到一个实际的服务器上,它会运行得更快!【参考方案3】:

这应该是可行的。您必须实现 onFailure,因为如果没有可用的服务器,它将被调用。

为 AsyncCallback 创建一个类似这样的新类,(默认情况下 AsyncCallback 只有一个参数,你用两个实现了吗?):

public class UrlCallback implements AsyncCallback<String, String> 
    private String url1;
    private String url2;

    public UrlCallback(String url1, String url2) 
        this.url1 = url1;
        this.url2 = url2;

    
    @Override
    public void onSuccess(String result1, String result2) 

        //"Do what you want to do here"

    

    @Override
    public void onFailure(Throwable caught) 

        //Respond the static file here

    


我在我的情况下处理它,当我没有互联网连接时从本地存储服务器图像网址:

public class PictureCallback implements AsyncCallback<Picture> 
    private Image picture;
    private IAppRequestTransportSupport storage;
    private String storeId;

    public PictureCallback(String storeId, Image picture) 
        this.picture = picture;
        this.storage = new  AppLocalStorageSupport();
        this.storeId = storeId;
    
    @Override
    public void onSuccess(Picture result) 

        picture.setUrl(result.getImageUrl());
        storage.doOnSuccess(result.getImageUrl(), "picture"+storeId);

    

    @Override
    public void onFailure(Throwable caught) 

        try 
            String pic = storage.readFromLocaleStorage("picture"+storeId);
            if(pic != null && !pic.equals("")) 
                picture.setUrl(pic);
            
         catch (KeyNotFoundException e) 
            e.printStackTrace();
         catch (NoLocaleStorageSupportException e) 
            e.printStackTrace();
        
    


【讨论】:

以上是关于GWT RPC 调用在编译模式下不起作用的主要内容,如果未能解决你的问题,请参考以下文章

GWT Java rpc 调用工作;但是,替换 GWTBootstrap - rpc 调用不起作用

RPC 调用 - 静态方法不起作用

我在 tomcat 上部署了 GWT,现在 RPC 不起作用

使用 FLVPlayback 的视频在 .exe 模式下不起作用

NuxtServerInit 在 Vuex 模块模式下不起作用 - Nuxt.js

为啥小写 [i] 在可视块模式下不起作用?