Tôi đồng ý với pathed mà bạn nên chuyển hướng trong AsyncCallback
s. Tuy nhiên, bạn không cần sử dụng rõ ràng các tùy chỉnh gọi lại MyAsyncCallback
thay vì tiêu chuẩn GWT AsyncCallback
. Điều này là quan trọng ví dụ khi bạn đã có rất nhiều mã sử dụng callbacks tiêu chuẩn.
Khi bạn gọi GWT.create(MyService.class)
GWT tạo proxy cho giao diện dịch vụ MyServiceAsync
của bạn. Proxy này có trách nhiệm giao tiếp với máy chủ và gọi lại số gọi lại khi nhận dữ liệu từ máy chủ. Proxy được tạo bằng cách sử dụng GWT code generators mechanism và theo mặc định, GWT sử dụng lớp ServiceInterfaceProxyGenerator
để tạo các proxy này.
Bạn có thể mở rộng trình tạo mặc định này (ServiceInterfaceProxyGenerator
lớp) để tự động sử dụng MyAsyncCallbacks tùy chỉnh của bạn trong tất cả lời gọi lại. Gần đây chúng tôi đã làm chính xác điều đó trong một dự án. Dưới đây là mã nguồn mà chúng tôi đã sử dụng.
Mã cho MyAsyncCallback
, nó giống như một trong những trình bày bởi pathed:
package my.package.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public class MyAsyncCallback<T> implements AsyncCallback<T> {
private final AsyncCallback<T> asyncCallback;
public MyAsyncCallback(AsyncCallback<T> asyncCallback) {
this.asyncCallback = asyncCallback;
}
@Override
public void onFailure(Throwable caught) {
if (caught instanceof SessionTimeoutException) {
// redirect
return;
}
asyncCallback.onFailure(caught);
}
@Override
public void onSuccess(T result) {
asyncCallback.onSuccess(result);
}
}
Mã cho máy phát điện mã GWT (MyRpcRemoteProxyGenerator
):
package my.package.server;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.user.rebind.rpc.ProxyCreator;
import com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator;
public class MyRpcRemoteProxyGenerator extends ServiceInterfaceProxyGenerator {
@Override
protected ProxyCreator createProxyCreator(JClassType remoteService) {
return new MyProxyCreator(remoteService);
}
}
Và phát lớp helper (MyProxyCreator
):
package my.package.server;
import java.util.Map;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.user.rebind.SourceWriter;
import com.google.gwt.user.rebind.rpc.ProxyCreator;
import com.google.gwt.user.rebind.rpc.SerializableTypeOracle;
public class MyProxyCreator extends ProxyCreator {
private final String methodStrTemplate = "@Override\n"
+ "protected <T> com.google.gwt.http.client.Request doInvoke(ResponseReader responseReader, "
+ "String methodName, int invocationCount, String requestData, "
+ "com.google.gwt.user.client.rpc.AsyncCallback<T> callback) {\n"
+ "${method-body}" + "}\n";
public MyProxyCreator(JClassType serviceIntf) {
super(serviceIntf);
}
@Override
protected void generateProxyMethods(SourceWriter w,
SerializableTypeOracle serializableTypeOracle,
Map<JMethod, JMethod> syncMethToAsyncMethMap) {
// generate standard proxy methods
super.generateProxyMethods(w, serializableTypeOracle,
syncMethToAsyncMethMap);
// generate additional method
overrideDoInvokeMethod(w);
}
private void overrideDoInvokeMethod(SourceWriter w) {
StringBuilder methodBody = new StringBuilder();
methodBody
.append("final com.google.gwt.user.client.rpc.AsyncCallback newAsyncCallback = new my.package.client.MyAsyncCallback(callback);\n");
methodBody
.append("return super.doInvoke(responseReader, methodName, invocationCount, requestData, newAsyncCallback);\n");
String methodStr = methodStrTemplate.replace("${method-body}",
methodBody);
w.print(methodStr);
}
}
Cuối cùng, bạn cần đăng ký trình tạo mã mới để sử dụng cho việc tạo proxy cho các dịch vụ không đồng bộ. Điều này được thực hiện bằng cách thêm vào tệp cấu hình GWT của bạn (gwt.tập tin xml):
<generate-with
class="my.package.server.MyRpcRemoteProxyGenerator">
<when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService" />
</generate-with>
Lúc đầu nó có vẻ là một giải pháp rất phức tạp :) nhưng nó có ưu điểm của nó:
- Bạn vẫn có thể sử dụng tiêu chuẩn GWT
AsyncCallback
s
- Bạn có thể thực thi chuyển hướng khi hết phiên trên toàn cầu cho ứng dụng của bạn
- Bạn có thể dễ dàng điều chỉnh và tắt (bằng cách thêm hoặc xóa
generate-with
trong tệp cấu hình GWT)
Điều này thật thông minh. Tôi nghĩ rằng nó sẽ dumbfound một nhà phát triển mới trên một dự án, như sẽ không có tài liệu tham khảo khó điều hướng thông qua IDE để khám phá cách MyAsyncCallback được gọi thay vì AsyncCallback. Tuy nhiên tôi thực sự thích rằng nó là một điểm cắt duy nhất cho việc áp dụng các sửa chữa hơn là phải luôn luôn sử dụng gọi lại tùy chỉnh vì sợ rằng một lỗi resurface. –
@Piotr là 'SessionTimeoutException' một lớp ngoại lệ tùy chỉnh mà bạn đã viết? Nếu vậy, bạn có muốn chia sẻ nó không? –
@AnishSana Xin lỗi, đã khá lâu rồi. Tôi không có quyền truy cập vào mã này vào lúc này. – Piotr