Syam Kumar S
Syam Kumar S

Reputation: 832

Gwt Request builder - how to return the response string

I need to implement a function that calls a web service and return the response.

I tried

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

On calling getFolderJson() the web service is called succesfully. But result is returned before the respnse is recieved. So I am getting the retunr value "initial_value".
How to return the value from the response when getFolderJson() function ?

Upvotes: 11

Views: 11813

Answers (3)

Alicia
Alicia

Reputation: 174

Try the same solution offered above except not with an anonymous Callback.

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

Upvotes: 0

GWT does not support synchronous Ajax, so you have to code your app using asynchronous pattern.

The low level object that GWT uses to perform the request is a XMLHttpRequest (except for old IE versions), and GWT always calls it's open() method with async set to true. So the only way to have synchronous ajax is maintaining your own modified version of XMLHttpRequest.java. But synchronous ajax is a bad idea, and even jQuery has deprecated this possibility.

So the normal way in gwt should be that your method returns void, and you passes an additional parameter with a callback to execute when the response is available.

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

I'd rather gwtquery Promises syntax for this instead of request-builder one:

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

Upvotes: 7

BlackJoker
BlackJoker

Reputation: 3191

I guess the builder.sendRequest(xxx) will return something like a Future,and you can get the result from that object.What you are using is an asynchronous method of RequestBuilder,there should be some synchronous method as well.

what does RequestBuilder come from? I can check the api for you.

OK,try this:

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

It seems RequestBuilder does not have any Synchronous method to get the result only a callback.

Be careful this method will block until the response is recieved. If this method is called in an event processing thread of gwt,this would be a bad practice.

Upvotes: 1

Related Questions