Estoy de acuerdo con pathed que debe hacer en la reorientación de sus AsyncCallback
s. Sin embargo, no necesita utilizar explícitamente sus devoluciones de llamada MyAsyncCallback
personalizadas en lugar de GWT estándar AsyncCallback
. Esto es importante, por ejemplo, cuando ya tienes un montón de código que utiliza devoluciones de llamadas estándar.
Al invocar GWT.create(MyService.class)
, GWT genera un proxy para su interfaz de servicio MyServiceAsync
. Este proxy es responsable de comunicarse con el servidor y invocando sus callbacks cuando obtiene datos del servidor. Los proxies se generan usando GWT code generators mechanism y de forma predeterminada GWT usa la clase ServiceInterfaceProxyGenerator
para generar estos proxies.
Se puede extender este generador por defecto (ServiceInterfaceProxyGenerator
clase) utilizar automáticamente sus MyAsyncCallbacks personalizados en todas las invocaciones devoluciones de llamada. Recientemente hicimos exactamente eso en un proyecto. Debajo hay un código fuente que usamos.
Código de MyAsyncCallback
, es idéntica a la presentada por 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);
}
}
Código para el generador de código de 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);
}
}
Y generador de clase auxiliar (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);
}
}
Finalmente, debe registrar el nuevo generador de códigos que se utilizará para generar proxies para servicios asíncronos. Esto se hace agregando esto a su archivo de configuración de GWT (gwt.archivo XML):
<generate-with
class="my.package.server.MyRpcRemoteProxyGenerator">
<when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService" />
</generate-with>
Al principio puede parecer ser una solución muy complicada :) pero tiene sus puntos fuertes:
- Puede seguir utilizando estándar GWT
AsyncCallback
s
- Puede imponer el redireccionamiento cuando la sesión agota el tiempo de su aplicación
- Puede activar y desactivar fácilmente (agregando o eliminando
generate-with
en sus archivos de configuración de GWT)
Esto es diabólicamente inteligente. Creo que confundiría a un nuevo desarrollador en un proyecto, ya que no habría referencias hard navegables a través del IDE para descubrir cómo se llama a MyAsyncCallback en lugar de AsyncCallback. Sin embargo, me gusta mucho que sea un único punto de corte para aplicar la corrección en lugar de tener que usar siempre la devolución de llamada personalizada para que no vuelva a aparecer un error. –
@Piotr ¿Es 'SessionTimeoutException' una clase de excepción personalizada que usted escribió? Si es así, ¿te importaría compartirlo? –
@AnishSana Lo siento, fue hace bastante tiempo. No tengo acceso a este código en este momento. – Piotr