问题描述
在我的GWT应用程序中,使用许多不同的服务,有许多对服务器的异步调用.为了进行更好的错误处理,我想包装所有回调,以便可以在一个地方处理类似InvocationExceptions
的异常.实现AsyncCallback
的超类并不是真正的选择,因为那意味着我将不得不修改每个异步调用.
Throughout my GWT app there are many different async calls to the server, using many different services. In order to do better error handling I want to wrap all my callbacks so that I can handle exceptions like InvocationExceptions
in one place. A super class implementing AsyncCallback
isn't really an option because that would mean that I would have to modify every async call.
RpcServiceProxy#doCreateRequestCallback()
看起来像是要覆盖的方法.很简单.我只是看不到如何让GWT使用我的新课程.
RpcServiceProxy#doCreateRequestCallback()
looks like the method to override. Simple enough. I just can't see how to make GWT use my new class.
陈述问题的另一种方式是
Another way to state the question would be
推荐答案
为了包装传递给任何RemoteService
的每个AsynCallback<T>
,您需要覆盖RemoteServiceProxy#doCreateRequestCallback()
,因为每个AsynCallback<T>
都在此之前提交发生RPC调用.
In order to wrap every AsynCallback<T>
that is passed to any RemoteService
you need to override RemoteServiceProxy#doCreateRequestCallback()
because every AsynCallback<T>
is handed in here before an RPC call happens.
正如@ChrisLercher所暗示的,您需要定义自己的代理生成器,以在每次生成RemoteService
代理时加入.首先扩展ServiceInterfaceProxyGenerator
并覆盖#createProxyCreator()
.
As @ChrisLercher alluded, you need to define your own Proxy Generator to step in every time a RemoteService
proxy gets generated. Start by extending ServiceInterfaceProxyGenerator
and overriding #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
类型的东西时,都使用Proxy Generator进行编译:
In your MyModule.gwt.xml
make use of deferred binding to instruct GWT to compile using your Proxy Generator whenever it generates something of the type 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
定义基类.
Extend ProxyCreator
and override #getProxySupertype()
. Use it in MyServiceInterfaceProxyGenerator#createProxyCreator()
so that you can define the base class for all the generated 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的程序包中.否则,您将看到这样的错误:
Make sure both your MyProxyCreator
and your MyServiceInterfaceProxyGenerator
are located in a package that will not get cross-compiled by GWT into javascript. Otherwise you will see an error like this:
[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
)添加到要交叉编译的客户端软件包中.
You are now ready to extend RemoteServiceProxy
and override #doCreateRequestCallback()
! Here you can do anything you like and apply it to every callback that goes to your server. Make sure that you add this class, and any other class you use here, in my case AsyncCallbackProxy
, to your client package to be cross-compiled.
/**
* 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));
}
}
参考:
References:
- DevGuideCodingBasicsDeferred.html
- An example applied to performance tracking
这篇关于如何将每个回调都包装在一个地方以改善错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!