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

Java GWT RPC调用在编译模式下不工作,java,ajax,gwt,rpc,Java,Ajax,Gwt,Rpc,我正在构建一个GWT应用程序。以前,每当我从web页面请求一个图像时,该请求就会转到一个客户机类,该类用于提供图像。这适用于GWT生成的URL以及编译后的独立文件URL 但是现在我已经用对服务器的Ajax-RPC调用替换了这一部分,其中服务器端类从客户机类接收必要的参数,并提供由客户机类发送到UI的图像。这在GWT生成URL时效果很好,但在编译之后,当我试图通过在URL栏中提供文件的路径将其作为独立HTML运行时,不会触发Ajax请求 这是因为RPC调用需要一个服务器来响应,而jQueryAja

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

但是现在我已经用对服务器的Ajax-RPC调用替换了这一部分,其中服务器端类从客户机类接收必要的参数,并提供由客户机类发送到UI的图像。这在GWT生成URL时效果很好,但在编译之后,当我试图通过在URL栏中提供文件的路径将其作为独立HTML运行时,不会触发Ajax请求

这是因为RPC调用需要一个服务器来响应,而jQueryAjax调用仅在桌面上就可以很好地工作?如何在桌面模式下模拟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) {...}
});

你是说如果你直接从文件系统打开HTML主机页?这无法工作,因为您当时没有服务器。这样就没有服务器端可以响应您的RPC调用。您必须在类似Tomcat或Jetty的servlet容器中运行GWT应用程序,以便服务器端RPC servlet正在运行并准备好响应来自客户端的RPC调用

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


你可能会将数据嵌入到应用程序中,以实现某种桌面模式。但我不知道这是否是你的目的?

你的意思是如果你直接从文件系统打开HTML主机页?这无法工作,因为您当时没有服务器。这样就没有服务器端可以响应您的RPC调用。您必须在类似Tomcat或Jetty的servlet容器中运行GWT应用程序,以便服务器端RPC servlet正在运行并准备好响应来自客户端的RPC调用

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


你可能会将数据嵌入到应用程序中,以实现某种桌面模式。但我不知道这是否是你的目的?

你完全脱离了GWT结构

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

即使没有服务器在运行,如果您从文件系统(如C://myapp/myapp.html)访问html文件。浏览器将作为一个静态web服务

当然,在html页面中会有你的app.nochahe.js,它是纯javascript

因此,浏览器毫不犹豫地显示所有内容。但它永远不会成为所谓的web应用程序,也永远不会生成任何ajax或任何其他服务器

打电话

在您的情况下,您并没有运行任何服务器,并以静态页面的形式访问它们,并期望它们连接服务器并带来您的数据,这是完全不可能的

因此,首先请在开发模式下运行| |调试代码

开始运行或调试项目后..在“开发模式”选项卡中生成的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是GWT与服务器通信的内部结构,通常它们都是impl类,这些类扩展了RemoteServiceServlet,它通过HTTP协议向客户端提供数据,如果不运行服务器,就不可能调用它们


如果您仍然对不同的GWT应用程序模式感到困惑,请参考这些差异,您完全脱离了GWT结构

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

即使没有服务器在运行,如果您从文件系统(如C://myapp/myapp.html)访问html文件。浏览器将作为一个静态web服务

当然,在html页面中会有你的app.nochahe.js,它是纯javascript

因此,浏览器毫不犹豫地显示所有内容。但它永远不会成为所谓的web应用程序,也永远不会生成任何ajax或任何其他服务器

打电话

在您的情况下,您没有运行任何服务器,也没有作为静态页面和expec访问它们 让他们连接服务器并带来您的数据,这是不可能的

因此,首先请在开发模式下运行| |调试代码

开始运行或调试项目后..在“开发模式”选项卡中生成的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是GWT与服务器通信的内部结构,通常它们都是impl类,这些类扩展了RemoteServiceServlet,它通过HTTP协议向客户端提供数据,如果不运行服务器,就不可能调用它们


如果您仍然对不同的GWT应用模式感到困惑,请参考此差异,这应该是可行的。您必须实现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

    }

}
在我的情况下,当我没有internet连接时,我会从localstorage处理服务器图像URL:

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

}

这应该是可行的。您必须实现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

    }

}
在我的情况下,当我没有internet连接时,我会从localstorage处理服务器图像URL:

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

}


很高兴看到..如果你发布完整的rpc调用..你说的桌面模式是什么意思?我的意思是,定位文件的路径名为foo.html,比如说,在war目录中,foo.java是调用'onModuleLoad'的类,只需在URL栏中输入它,像C://Users/Cupidvogel/Desktop/Workspace/foo/war/foo.html……你想从impl类中获取路径并在客户端上显示它们吗?我没听清楚。你能详细说明一下吗?如果你发布完整的rpc调用,那会很高兴看到…你说的桌面模式是什么意思?我的意思是,找到文件的路径,一个名为foo.html的文件,比如说,在war目录中,foo.java是调用'onModuleLoad'的类,只需在URL栏中输入它,像C://Users/Cupidvogel/Desktop/Workspace/foo/war/foo.html……你想从impl类中获取路径并在客户端上显示它们吗?我没听清楚。你能详细解释一下吗?谢谢你,阿德里安。是的,我也怀疑没有服务器RPC就不能工作。但是,我如何向客户机提供页面呢?在GWT生成的URL模式下,页面非常不稳定,每个clickhandler或动画都需要几年才能完成。但是在桌面模式下,一切运行都和普通JS一样平稳。当然,我不能向客户提供那个URL,对吧,在那里他会有可怕的UI体验?那么,客户端如何在服务器上像在普通HTML-JS生成的页面中一样轻松地访问该页面呢?我不太明白为什么要在服务器上创建图像URL。你是在动态地创建图像吗?如果没有,只需将图像与主机页或某个子文件夹放在同一文件夹中,然后计算客户端上的URL。应该可以帮助您创建图像URL。如果服务器做了一些重要的事情,而你真的需要一台服务器,那么除了将你的应用部署到测试服务器并向你的客户发送所述服务器的URL之外,别无选择。是的,当我在我的桌面上测试GWT应用时,作为GWT生成的代码,而不进行编译,因此,当您关闭服务器时,页面将显示断开连接的模式对话,页面非常混乱,每个事件都需要大量时间触发,无论是菜单上的简单下拉调用,还是单击某个元素后弹出警报。但是,当我编译相同的代码,并通过其文件URL在浏览器中查看页面时,它的行为通常与使用HTML-CSS-JS构建的页面类似。因此,如果客户端通过GWT生成的URL访问该页面,那么这种不连贯性还会持续吗?我假设您从IDE以所谓的方式运行应用程序。Dev模式很慢,它做了各种事情,允许您在IDE中进行调试和重新加载。一旦你编译了你的应用程序并将其安装到实际的服务器上,它就会运行得更快!谢谢你,阿德里安。是的,我也怀疑没有服务器RPC就不能工作。但是,我如何向客户机提供页面呢?在GWT生成的URL模式下,页面非常不稳定,每个clickhandler或动画都需要几年才能完成。但是在桌面模式下,一切运行都和普通JS一样平稳。当然,我不能向客户提供那个URL,对吧,在那里他会有可怕的UI体验?那么,客户机如何像在普通HTML-J中一样轻松地在服务器中访问该页面呢
我不太明白为什么要在服务器上创建图像URL。你是在动态地创建图像吗?如果没有,只需将图像与主机页或某个子文件夹放在同一文件夹中,然后计算客户端上的URL。应该可以帮助您创建图像URL。如果服务器做了一些重要的事情,而你真的需要一台服务器,那么除了将你的应用部署到测试服务器并向你的客户发送所述服务器的URL之外,别无选择。是的,当我在我的桌面上测试GWT应用时,作为GWT生成的代码,而不进行编译,因此,当您关闭服务器时,页面将显示断开连接的模式对话,页面非常混乱,每个事件都需要大量时间触发,无论是菜单上的简单下拉调用,还是单击某个元素后弹出警报。但是,当我编译相同的代码,并通过其文件URL在浏览器中查看页面时,它的行为通常与使用HTML-CSS-JS构建的页面类似。因此,如果客户端通过GWT生成的URL访问该页面,那么这种不连贯性还会持续吗?我假设您从IDE以所谓的方式运行应用程序。Dev模式很慢,它做了各种事情,允许您在IDE中进行调试和重新加载。一旦你编译了你的应用程序并将其安装到实际的服务器上,它就会运行得更快!