6

在我的 GWT 应用程序中,有许多对服务器的不同异步调用,使用许多不同的服务。为了更好地处理错误,我想包装我的所有回调,以便我可以InvocationExceptions在一个地方处理异常。实现超类AsyncCallback并不是一个真正的选择,因为这意味着我必须修改每个异步调用。

RpcServiceProxy#doCreateRequestCallback()看起来像要覆盖的方法。很简单。我只是看不到如何让 GWT 使用我的新课程。

陈述问题的另一种方式是

如何让 GWT 使用我自己的子类RpcServiceProxy

4

4 回答 4

9

为了包装每一个AsynCallback<T>传递给任何RemoteService你需要覆盖的东西,RemoteServiceProxy#doCreateRequestCallback()因为每一个AsynCallback<T>都是在 RPC 调用发生之前提交的。

以下是执行此操作的步骤:

正如@ChrisLercher 所暗示的,您需要定义自己的代理生成器,以便在每次RemoteService生成代理时介入。从扩展ServiceInterfaceProxyGenerator和覆盖开始#createProxyCreator()

/**
 * This Generator extends the default GWT {@link ServiceInterfaceProxyGenerator} and replaces it in the
 * co.company.MyModule GWT module for all types that are assignable to
 * {@link com.google.gwt.user.client.rpc.RemoteService}. Instead of the default GWT {@link ProxyCreator} it provides the
 * {@link MyProxyCreator}.
 */
public class MyServiceInterfaceProxyGenerator extends ServiceInterfaceProxyGenerator {
    @Override
    protected ProxyCreator createProxyCreator(JClassType remoteService) {
        return new MyProxyCreator(remoteService);
    }
}

在您MyModule.gwt.xml使用延迟绑定来指示 GWT 在生成以下内容时使用您的代理生成器进行编译RemoteService

<generate-with 
   class="com.company.ourapp.rebind.rpc.MyServiceInterfaceProxyGenerator">
    <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/>
</generate-with>

扩展ProxyCreator和覆盖#getProxySupertype(). 使用它,MyServiceInterfaceProxyGenerator#createProxyCreator()以便您可以为所有生成的RemoteServiceProxies.

/**
 * This proxy creator extends the default GWT {@link ProxyCreator} and replaces {@link RemoteServiceProxy} as base class
 * of proxies with {@link MyRemoteServiceProxy}.
 */
public class MyProxyCreator extends ProxyCreator {
    public MyProxyCreator(JClassType serviceIntf) {
        super(serviceIntf);
    }

    @Override
    protected Class<? extends RemoteServiceProxy> getProxySupertype() {
        return MyRemoteServiceProxy.class;
    }
}

确保你MyProxyCreator和你MyServiceInterfaceProxyGenerator都位于一个不会被 GWT 交叉编译成 javascript 的包中。否则你会看到这样的错误:

[ERROR] Line XX: No source code is available for type com.google.gwt.user.rebind.rpc.ProxyCreator; did you forget to inherit a required module?

您现在已准备好扩展RemoteServiceProxy和覆盖#doCreateRequestCallback()!在这里,您可以做任何您喜欢的事情,并将其应用于发送到您服务器的每个回调。确保将此类以及您在此处使用的任何其他类(在我的情况下AsyncCallbackProxy)添加到要交叉编译的客户端包中。

/**
 * The remote service proxy extends default GWT {@link RemoteServiceProxy} and proxies the {@link AsyncCallback} with
 * the {@link AsyncCallbackProxy}.
 */
public class MyRemoteServiceProxy extends RemoteServiceProxy {
    public MyRemoteServiceProxy(String moduleBaseURL, String remoteServiceRelativePath, String serializationPolicyName,
                                 Serializer serializer) {
        super(moduleBaseURL, remoteServiceRelativePath, serializationPolicyName, serializer);
    }

    @Override
    protected <T> RequestCallback doCreateRequestCallback(RequestCallbackAdapter.ResponseReader responseReader,
                                                          String methodName, RpcStatsContext statsContext,
                                                          AsyncCallback<T> callback) {
        return super.doCreateRequestCallback(responseReader, methodName, statsContext, new AsyncCallbackProxy<T>(callback));
    }
}

参考:

于 2013-07-04T15:34:00.773 回答
2

您正在寻找的类型可能是RemoteServiceProxy(不是RpcServiceProxy),我假设您应该从覆盖默认绑定开始/com/google/gwt/user/RemoteService.gwt.xml(只需将这些行复制到您自己的 .gwt.xml 文件并进行调整):

<generate-with 
       class="com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator">
    <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/>
</generate-with>

在那里你会找到protected Class<? extends RemoteServiceProxy> getProxySupertype(),你可以覆盖它来返回你自己的RemoteServiceProxy类。

还没试过,所以这可能需要一些额外的步骤......

于 2013-07-01T15:38:43.467 回答
0

通常,GWT 处理异步进程中发生的异常的方式是通过UncaughtExceptionHandlers.

我会使用我自己的处理程序来管理这些异常:

GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
  public void onUncaughtException(Throwable e) {
    if (e instanceof WhateverException) {
      // handle the exception here
    }        
  }
});

使用它你不需要子类化任何东西。

于 2013-07-01T15:39:07.577 回答
0

如果“一个地方”的意思是“我想用一种方法处理所有错误”,那么我建议要么捕获并扔东西直到它们在一个地方,要么创建一个EventBus你基本上只是将每个错误发送到的地方。然后,您只需将一个处理程序连接到该总线即可处理所有事情。

于 2013-07-01T22:09:35.403 回答