异步开始和结束时的 Resty-GWT 自定义回调
Resty-GWT custom callback on async start and end
我使用 resty gwt 进行所有服务器通信。我想要一些指示器来显示操作正在进行中。
我考虑了 2 个方法:
- 进度条,将显示进度百分比;
- 动画,在操作过程中会显示,但没有任何百分比。
我假设我需要添加带有回调的自定义过滤器。
我想触发事件,例如:RestyGwtComunicationStart
和 RestyGwtComunicationEnd
,或者回调触发 onComunicationStarted
和
onComunicationEnded
。我想在一个地方声明它,RestyGWT Dispatcher 配置。另外,如果有错误我想获取错误。
但我不知道从哪里开始。文档中没有关于它的说法。
我可以向你求助吗?我该怎么做?
因此,如果您想知道请求是否已发送,则由您在 GWT 应用程序中进行处理。您可以在触发请求时发送事件。您有多种方法可以做到这一点。
查看文档中的 Request Dispatcher https://resty-gwt.github.io/documentation/restygwt-user-guide.html
那么如果你想获取进度信息,因为 HTTP 调用是同步的。所以没有办法轻松做到这一点。
我一直这样做的方式如下:
1) 创建第一个调用以使用 POST 在后端启动处理,这将 return 您的处理 ID
2) 然后对您的处理 ID 执行 GET,这将 return 进度。一旦进度达到 100%,它将 return 结果的 ID
3) 得到结果ID
的结果
(您最终可以将 2 和 3 混合在一起,并且 return 在同一 DTO 中进度为 100% 时产生结果)
另一种选择是通过将信息从后端推送到前端来替换 2) (html5 websocket)
有人已经将它作为对 resty 的拉取请求。猜猜你可以试试看:
不幸的是 "Dispatcher/Callback filters" 功能没有在官方文档中描述。但我可以建议下一个解决方案(此代码应放在模块的 EntryPoint 实现中):
public void onModuleLoad() {
//...
//used to show busy indicator before send HTTP request
DispatcherFilter busyIndicatorDispatcherFilter = new DispatcherFilter() {
@Override
public boolean filter(Method method, RequestBuilder builder) {
BusyIndicator.show();
return true;
}
};
//used to show busy indicator after HTTP response recieved
CallbackFilter busyIndicatorCallbackFilter = new CallbackFilter() {
@Override
public RequestCallback filter(Method method, Response response, RequestCallback callback) {
BusyIndicator.hide();
return callback;
}
};
//registering FilterawareDispatcher (and busy indicator filters) as default Dispatcher
Defaults.setDispatcher(new DefaultFilterawareDispatcher(
busyIndicatorDispatcherFilter,
new DefaultDispatcherFilter(new DefaultCallbackFactory(busyIndicatorCallbackFilter))));
//...
}
不幸的是我没有得到足够的答案,所以我开发了自己的解决方案。
起初我在我的模块配置中添加了 Resty 配置RestyGwtConfig
public class ClientModule extends AbstractPresenterModule {
@Override
protected void configure() {
bind(RestyGwtConfig.class).asEagerSingleton();
install(new DefaultModule.Builder()
.defaultPlace(Routing.HOME.url)
.errorPlace(Routing.ERROR.url)
.unauthorizedPlace(Routing.LOGIN.url)
.tokenFormatter(RouteTokenFormatter.class).build());
install(new AppModule());
install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));
bind(ResourceLoader.class).asEagerSingleton();
}
}
然后我为 resty gwt 的所有通信请求设置了 Custom distpatcher。
import org.fusesource.restygwt.client.Defaults;
import org.fusesource.restygwt.client.Resource;
import pl.korbeldaniel.cms.shared.ServiceRouting;
import com.google.gwt.core.client.GWT;
import com.google.inject.Inject;
public class RestyGwtConfig {
@Inject
public RestyGwtConfig(RestyDispatcher dispatcher) {
Defaults.setDispatcher(dispatcher);
}
}
然后我添加了自定义过滤器 (ProgressIndicatorFilter
) 来处理通信的 start 和 end 回调:
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.dispatcher.DefaultFilterawareDispatcher;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestException;
import com.google.inject.Inject;
public class RestyDispatcher extends DefaultFilterawareDispatcher {
@Inject
public RestyDispatcher(ProgressIndicatorFilter progressIndicatorFilter) {
addFilter(progressIndicatorFilter);
}
}
在过滤器 class 中覆盖了方法 filter
我添加了一个事件触发器 (eventBus.fireEvent(new IndicatorEvent("Rest-Gwt Comunication started"));
) 并注册了回调,这里是完整代码:
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.dispatcher.DispatcherFilter;
import pl.korbeldaniel.cms.client.template.progressIndicator.IndicatorEvent;
import com.google.gwt.http.client.RequestBuilder;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
class ProgressIndicatorFilter implements DispatcherFilter {
private AssistedInjectionFactory factory;
private EventBus eventBus;
@Inject
public ProgressIndicatorFilter(AssistedInjectionFactory factory, EventBus eventBus) {
this.factory = factory;
this.eventBus = eventBus;
}
@Override
public boolean filter(Method method, RequestBuilder builder) {
builder.setCallback(factory.createProgressIndicatorCallback(method));
eventBus.fireEvent(new IndicatorEvent("Resty-Gwt Comunication started"));
return true;
}
}
无法直接注册回调,例如
new ProgressIndicatorDispatcherCallback()
因为我使用依赖注入。所以我创建了一个工厂来辅助注入如下:
public interface AssistedInjectionFactory {
ProgressIndicatorDispatcherCallback createProgressIndicatorCallback(Method method);
}
and 您可以找到更多辅助注射信息。
回调代码如下:
class ProgressIndicatorDispatcherCallback implements RequestCallback {
private RequestCallback requestCallback;
private EventBus eventBus;
@Inject
public ProgressIndicatorDispatcherCallback(@Assisted Method method, EventBus eventBus) {
this.requestCallback = method.builder.getCallback();
this.eventBus = eventBus;
}
@Override
public void onResponseReceived(Request request, Response response) {
endComunicationFireIvent();
requestCallback.onResponseReceived(request, response);
}
@Override
public void onError(Request request, Throwable exception) {
endComunicationFireIvent();
requestCallback.onError(request, exception);
}
private void endComunicationFireIvent() {
eventBus.fireEvent(new IndicatorEvent("Rest-Gwt Comunication ended"));
}
}
我使用 resty gwt 进行所有服务器通信。我想要一些指示器来显示操作正在进行中。
我考虑了 2 个方法:
- 进度条,将显示进度百分比;
- 动画,在操作过程中会显示,但没有任何百分比。
我假设我需要添加带有回调的自定义过滤器。
我想触发事件,例如:RestyGwtComunicationStart
和 RestyGwtComunicationEnd
,或者回调触发 onComunicationStarted
和
onComunicationEnded
。我想在一个地方声明它,RestyGWT Dispatcher 配置。另外,如果有错误我想获取错误。
但我不知道从哪里开始。文档中没有关于它的说法。
我可以向你求助吗?我该怎么做?
因此,如果您想知道请求是否已发送,则由您在 GWT 应用程序中进行处理。您可以在触发请求时发送事件。您有多种方法可以做到这一点。
查看文档中的 Request Dispatcher https://resty-gwt.github.io/documentation/restygwt-user-guide.html
那么如果你想获取进度信息,因为 HTTP 调用是同步的。所以没有办法轻松做到这一点。
我一直这样做的方式如下:
1) 创建第一个调用以使用 POST 在后端启动处理,这将 return 您的处理 ID
2) 然后对您的处理 ID 执行 GET,这将 return 进度。一旦进度达到 100%,它将 return 结果的 ID
3) 得到结果ID
的结果(您最终可以将 2 和 3 混合在一起,并且 return 在同一 DTO 中进度为 100% 时产生结果)
另一种选择是通过将信息从后端推送到前端来替换 2) (html5 websocket)
有人已经将它作为对 resty 的拉取请求。猜猜你可以试试看:
不幸的是 "Dispatcher/Callback filters" 功能没有在官方文档中描述。但我可以建议下一个解决方案(此代码应放在模块的 EntryPoint 实现中):
public void onModuleLoad() {
//...
//used to show busy indicator before send HTTP request
DispatcherFilter busyIndicatorDispatcherFilter = new DispatcherFilter() {
@Override
public boolean filter(Method method, RequestBuilder builder) {
BusyIndicator.show();
return true;
}
};
//used to show busy indicator after HTTP response recieved
CallbackFilter busyIndicatorCallbackFilter = new CallbackFilter() {
@Override
public RequestCallback filter(Method method, Response response, RequestCallback callback) {
BusyIndicator.hide();
return callback;
}
};
//registering FilterawareDispatcher (and busy indicator filters) as default Dispatcher
Defaults.setDispatcher(new DefaultFilterawareDispatcher(
busyIndicatorDispatcherFilter,
new DefaultDispatcherFilter(new DefaultCallbackFactory(busyIndicatorCallbackFilter))));
//...
}
不幸的是我没有得到足够的答案,所以我开发了自己的解决方案。
起初我在我的模块配置中添加了 Resty 配置RestyGwtConfig
public class ClientModule extends AbstractPresenterModule {
@Override
protected void configure() {
bind(RestyGwtConfig.class).asEagerSingleton();
install(new DefaultModule.Builder()
.defaultPlace(Routing.HOME.url)
.errorPlace(Routing.ERROR.url)
.unauthorizedPlace(Routing.LOGIN.url)
.tokenFormatter(RouteTokenFormatter.class).build());
install(new AppModule());
install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));
bind(ResourceLoader.class).asEagerSingleton();
}
}
然后我为 resty gwt 的所有通信请求设置了 Custom distpatcher。
import org.fusesource.restygwt.client.Defaults;
import org.fusesource.restygwt.client.Resource;
import pl.korbeldaniel.cms.shared.ServiceRouting;
import com.google.gwt.core.client.GWT;
import com.google.inject.Inject;
public class RestyGwtConfig {
@Inject
public RestyGwtConfig(RestyDispatcher dispatcher) {
Defaults.setDispatcher(dispatcher);
}
}
然后我添加了自定义过滤器 (ProgressIndicatorFilter
) 来处理通信的 start 和 end 回调:
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.dispatcher.DefaultFilterawareDispatcher;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestException;
import com.google.inject.Inject;
public class RestyDispatcher extends DefaultFilterawareDispatcher {
@Inject
public RestyDispatcher(ProgressIndicatorFilter progressIndicatorFilter) {
addFilter(progressIndicatorFilter);
}
}
在过滤器 class 中覆盖了方法 filter
我添加了一个事件触发器 (eventBus.fireEvent(new IndicatorEvent("Rest-Gwt Comunication started"));
) 并注册了回调,这里是完整代码:
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.dispatcher.DispatcherFilter;
import pl.korbeldaniel.cms.client.template.progressIndicator.IndicatorEvent;
import com.google.gwt.http.client.RequestBuilder;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
class ProgressIndicatorFilter implements DispatcherFilter {
private AssistedInjectionFactory factory;
private EventBus eventBus;
@Inject
public ProgressIndicatorFilter(AssistedInjectionFactory factory, EventBus eventBus) {
this.factory = factory;
this.eventBus = eventBus;
}
@Override
public boolean filter(Method method, RequestBuilder builder) {
builder.setCallback(factory.createProgressIndicatorCallback(method));
eventBus.fireEvent(new IndicatorEvent("Resty-Gwt Comunication started"));
return true;
}
}
无法直接注册回调,例如
new ProgressIndicatorDispatcherCallback()
因为我使用依赖注入。所以我创建了一个工厂来辅助注入如下:
public interface AssistedInjectionFactory {
ProgressIndicatorDispatcherCallback createProgressIndicatorCallback(Method method);
}
回调代码如下:
class ProgressIndicatorDispatcherCallback implements RequestCallback {
private RequestCallback requestCallback;
private EventBus eventBus;
@Inject
public ProgressIndicatorDispatcherCallback(@Assisted Method method, EventBus eventBus) {
this.requestCallback = method.builder.getCallback();
this.eventBus = eventBus;
}
@Override
public void onResponseReceived(Request request, Response response) {
endComunicationFireIvent();
requestCallback.onResponseReceived(request, response);
}
@Override
public void onError(Request request, Throwable exception) {
endComunicationFireIvent();
requestCallback.onError(request, exception);
}
private void endComunicationFireIvent() {
eventBus.fireEvent(new IndicatorEvent("Rest-Gwt Comunication ended"));
}
}