【问题标题】:Gwt Request builder - how to return the response stringGwt Request builder - 如何返回响应字符串
【发布时间】:2021-10-17 11:33:06
【问题描述】:

我需要实现一个调用 Web 服务并返回响应的函数。

我试过了

public String getFolderJson(String path) {  
           String result="initial_value";
           StringBuilder param = new StringBuilder();  
           param.append("?sessionId=").append(getSessionId());  
           param.append("&path=").append(path);  
           RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "https://localhost/folder" + param);  
                   try {  
                        builder.sendRequest(null, new RequestCallback() {  
                        @Override  
                        public void onResponseReceived(Request request,
                                Response response) {  
                              result = response.getText();
                              System.out.println(response.getText());  
                                            //I need to return "result"   
                        }  
                        @Override  
                        public void onError(Request request, Throwable exception) {}  
                          });  
                    return result; //the result get returned before the response is recieved.So i am getting the return value "initial_value".
                   }      
                   catch (RequestException e) {}  
        return null;
    }

在调用getFolderJson() 时,Web 服务被成功调用。但是result 在收到响应之前返回。所以我得到了返回值“initial_value”。
getFolderJson()函数时如何从响应中返回值?

【问题讨论】:

    标签: java gwt


    【解决方案1】:

    尝试上面提供的相同解决方案,但不使用匿名回调。

    public String getFolderJson(String path) { 
    
        RequestBuilder builder = new RequestBuilder(...);
        HttpCallback cb=new HttpCallback();
    
        try {
          builder.sendRequest(null, cb);
        } catch (RequestException e) {
        // exception handling
            logger.severe(cb.err);
        }  
    
        return cb.result;
    }
    
    class HttpCallback implements RequestCallback{
    
        String result;
        String err;
    
        HttpCallback(){}
    
        @Override
        public void onResponseReceived(Request request, Response response) {            
            result=response.getText());     
        }
    
        @Override
        public void onError(Request request, Throwable exception) {
            err=exception.getMessage();     
        }       
    }
    

    【讨论】:

      【解决方案2】:

      GWT 不支持同步 Ajax,因此您必须使用异步模式编写应用程序。

      GWT 用来执行请求的低级对象是XMLHttpRequest(旧的IE 版本除外),GWT 总是调用它的open() 方法并将async 设置为true。因此,拥有同步 ajax 的唯一方法是维护您自己修改后的 XMLHttpRequest.java 版本。但是同步 ajax 是个坏主意,甚至 jQuery 都弃用了这种可能性。

      所以gwt中的正常方式应该是你的方法返回void,然后你传递一个带有回调的附加参数,以便在响应可用时执行。

      public void getFolderJson(String path, Callback<String, String> callback) {  
          RequestBuilder builder = new RequestBuilder(...);
          try {
            builder.sendRequest(null, new RequestCallback() {  
              @Override  
              public void onResponseReceived(Request request, Response response) {
                callback.onSuccess(response.getText());  
              }  
              @Override  
              public void onError(Request request, Throwable exception) {}
                callback.onFailure(exception.getMessage());  
              });
          } catch (RequestException e) {
              callback.onFailure(exception.getMessage());  
          }  
      }
      

      我宁愿使用 gwtquery Promises 语法,而不是 request-builder 之一:

        Ajax.get("http://localhost/folder?sessionId=foo&path=bar")
          .done(new Function(){
            public void f() {
              String text = arguments(0);
            }
          });
      

      【讨论】:

      • 我有一个文件浏览器组件。当组件询问 foder 详细信息时,我需要返回 getFolderJson(...) 的结果。我不能用回调模式来做到这一点。
      • 我相信有一些方法可以更改您的代码以使用回调,这是所有 RIA 应用程序的工作方式,并且有很多或任何类型的应用程序。也许您可以通过调用getFolderJson 发布更大的代码,以便我们找到解决方案。无论如何,如果您继续想要使用同步 Ajax(我不鼓励这样做),只需将 XMLHttpRequest.java 及其完整路径复制到您的项目中,并将 this.open(httpMethod, url, true); 行更改为 this.open(httpMethod, url, false);
      【解决方案3】:

      我猜builder.sendRequest(xxx)会返回类似Future的东西,你可以从那个对象中得到结果。你使用的是RequestBuilder的异步方法,应该也有一些同步方法。

      RequestBuilder 从何而来?我可以帮你查一下api。

      好的,试试这个:

      public String getFolderJson(String path) {
          String result = "initial_value";
          StringBuilder param = new StringBuilder();
          param.append("?sessionId=").append(getSessionId());
          param.append("&path=").append(path);
          RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
                  "https://localhost/folder" + param);
          final SynchronousQueue resultQueue = new SynchronousQueue();
          try {
              builder.sendRequest(null, new RequestCallback() {
                  @Override
                  public void onResponseReceived(Request request,
                          Response response) {
                      resultQueue.put(response.getText());
                      System.out.println(response.getText());
                  }
      
                  @Override
                  public void onError(Request request, Throwable exception) {
                  }
              });
              return resultQueue.take();
          } catch (RequestException e) {
          }
          return result;
      }
      

      似乎RequestBuilder 没有任何同步方法来获取结果,只有回调。

      请注意,此方法将阻塞,直到收到响应。 如果在 gwt 的事件处理线程中调用此方法,这将是一个不好的做法。

      【讨论】:

      • 对其进行优化使其更健壮:onError(xxx,xxx){ resultQueue.put(result); } 和 setTimeoutMillis(xxx) 确保请求不会永远阻塞。
      • @Spring.Rush SynchronousQueue 不受gwt emulated jre 支持,所以你的代码永远不会编译成js。
      猜你喜欢
      • 1970-01-01
      • 2021-09-12
      • 2023-02-14
      • 2023-03-19
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多