Я согласен с pathed , что вы должны сделать перенаправление в ваших AsyncCallback
s. Однако вам не нужно явно использовать ваши собственные MyAsyncCallback
обратные вызовы вместо стандартного GWT AsyncCallback
. Это важно, например, когда у вас уже есть много кода, который использует стандартные обратные вызовы.
Когда вы вызываете GWT.create(MyService.class)
, GWT создает прокси для вашего MyServiceAsync
интерфейса службы. Этот прокси-сервер отвечает за связь с сервером и , вызывая ваши обратные вызовы при получении данных с сервера. Прокси генерируются с использованием механизма генерации кода GWT , и по умолчанию GWT использует класс ServiceInterfaceProxyGenerator
для генерации этих прокси.
Вы можете расширить этот генератор по умолчанию (ServiceInterfaceProxyGenerator
класс) , чтобы автоматически использовать ваши пользовательские MyAsyncCallbacks во всех вызовах обратных вызовов . Мы недавно сделали именно это в проекте. Ниже приведен исходный код, который мы использовали.
Код для MyAsyncCallback
, он идентичен тому, который представлен 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);
}
}
Код для генератора кода 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);
}
}
И вспомогательный класс генератора (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);
}
}
Наконец, вам нужно зарегистрировать новый генератор кода, который будет использоваться для генерации прокси для асинхронных сервисов. Это можно сделать, добавив это в файл конфигурации GWT (файл gwt.xml):
<generate-with
class="my.package.server.MyRpcRemoteProxyGenerator">
<when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService" />
</generate-with>
В начале это может показаться очень сложным решением :), но оно имеет свои сильные стороны:
- Вы все еще можете использовать стандартный GWT
AsyncCallback
s
- Вы можете принудительно перенаправить, когда для вашего приложения глобально истекает время сеанса
- Вы можете легко включать и выключать его (добавляя или удаляя
generate-with
в ваших конфигурационных файлах GWT)