我需要实现一个调用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服务。但是在收到respnse之前会返回result
。所以我得到了retunr值“initial_value”
如何在getFolderJson()
函数返回响应中的值?
答案 0 :(得分:7)
GWT不支持同步Ajax,因此您必须使用异步模式对应用程序进行编码。
GWT用于执行请求的低级别对象是XMLHttpRequest(旧的IE版本除外),并且GWT始终将其open()
方法调用为异步设置为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
语法而不是请求构建器:
Ajax.get("http://localhost/folder?sessionId=foo&path=bar")
.done(new Function(){
public void f() {
String text = arguments(0);
}
});
答案 1 :(得分:1)
我想builder.sendRequest(xxx)将返回类似Future的内容,你可以从该对象获得结果。你使用的是RequestBuilder的异步方法,也应该有一些同步方法。 / p>
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的事件处理线程中调用此方法,则这将是一种不好的做法。
答案 2 :(得分:0)
尝试上面提供的相同解决方案,但不使用匿名回调。
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();
}
}