I use resty gwt for all server communication. I would like some indicator that would show the operation is in progress.
I consider 2 aproaches:
- progressbar, which will show in progress percentage;
- animation, that will be showed while operation is in progress, but without any percantage.
I've assumed that I need to add custom filter with callback.
I would like to fire events like: RestyGwtComunicationStart and RestyGwtComunicationEnd, or callback to fire onComunicationStarted and
onComunicationEnded. I would like to have this declared in one place, RestyGWT Dispatcher configuration. Also if there was an error I would like to fetch the error.
But I don't know where to start. There is no word about it in documentations.
Can I ask You for help? How can I do this?
So if you want to know that a request has been sent it is up to you in your GWT app to treat that. You can send an event when you trigger your request. You have multiple way of doing this.
Have a look at Request Dispatcher inside the doc https://resty-gwt.github.io/documentation/restygwt-user-guide.html
Then if you want to get progress info, as HTTP calls are synchronous. So there is no way to do this easily.
The way I have been doing it is the following:
1) Create a first call to initiate a processing on the backend with a POST, this will return the ID of your processing
2) Then do a GET on your processing ID that will return the progress. Once the progress is 100% it will return the ID of the result
3) GET the result with the result ID
(You can mix 2 and 3 together eventually and return result when progress is 100% in the same DTO)
Another option is to replace 2) by pushing info from backend to front end (html5 websocket)
Someone already did it as a pull-request to resty. Guess you can give it a try:
Unfortunately "Dispatcher/Callback filters" feature does not described in the official documentation. But I can suggest next solution (this code should be placed in EntryPoint implementation of your module):
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))));
//...
}
Unfortunately I did not get adequate answer, So I developed my own solution.
At first I've added Resty configuration RestyGwtConfig to my Module configuration
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();
}
}
then I've set Custom distpatcher for all my comunication requests of resty gwt.
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);
}
}
Then I've added custom filter (ProgressIndicatorFilter) to handle communication's start and end callbacks:
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);
}
}
in filter class method overriden filter I've added an event trigger (eventBus.fireEvent(new IndicatorEvent("Rest-Gwt Comunication started"));) and registered callback, here is whole code:
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;
}
}
Registering a callback couldn't be done straight forward, like
new ProgressIndicatorDispatcherCallback()
cause I use dependency injection. So I've created a factory to assist injection as follow:
public interface AssistedInjectionFactory {
ProgressIndicatorDispatcherCallback createProgressIndicatorCallback(Method method);
}
Here and here You can find more Assisted Injection info.
Here is the callback code:
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"));
}
}
来源:https://stackoverflow.com/questions/38325236/resty-gwt-custom-callback-on-async-start-and-end