Default AsyncCallback in GWT - gwt

Doing my app, I got bored from always implement the same default error treatment (show a message, caught.printstacktrace and etc..) in the asynccallback onfailure.
I wonder if you can make a generic treatment or standard treatment, something like that.
Thanks.

I assume you are using standard GWT-RPC. Something like this might help
public abstract class AbstractCallBack<T> implements AsyncCallback<T>{
#Override
public void onFailure(Throwable caught) {
//Default error Handling code goes here
}
}
And whenever you use your service instead of instantiating an AsyncCallback you can instantiate this class and have generalized error handling.
SomeServiceAsync service = GWT.create(SomeService.class);
service.someMethod("Hello!", new AbstractCallBack<String>() {
#Override
public void onSuccess(String result) {
// TODO Auto-generated method stub
}
});

Related

Multiple ContainerRequestFilter for Jersey

We are planning on using Jersey's reference implementation for our REST APIs. As a prototype effort, I was also playing around with the ContainerRequestFilters and I implemented multiple of them. Is there a way in which we can control the order in which these filters are executed?
The scenario that I am thinking over here is to ensure that the security filter must be the first one to run, and if required establish the SecurityContext and then execute other filters.
Yes you can control this with the javax.annotation.Priority attribute and the default javax.ws.rs.Priorities. For example if you wanted:
Logging filter always runs first
Authentication filter should run next
Authorization filter should run next
Custom filter should always run after others
You could do:
#Priority(Integer.MIN_VALUE)
public class CustomLoggingFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
// DO LOGGING HERE, THIS RUNS FIRST
}
}
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
String authHeader = requestContext.getHeaderString(HttpHeaders.WWW_AUTHENTICATE);
// DO AUTHENTICATION HERE, THIS RUNS SECOND
}
}
#Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
String authHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// DO AUTHORIZATION HERE, THIS RUNS THIRD
}
}
#Priority(Priorities.USER)
public class MyAwesomeStuffFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
// DO AWESOME STUFF HERE, THIS RUNS LAST
}
}

Will an gwt rpc call ALWAYS callback to either my onsuccess or onfail methods?

I have implemented the suggestion in this post and disable my button after the the first click. How to prevent DoubleSubmit in a GWT application?
What i want to know is with my button reenabled in both my fail and success methods will it always get reenabled. Also is there any place i can put some code that i always want executed when the server replies as opposed to duplicating it in both fail and success methods
I do think that either onSuccess() or onFailure() will be called every time.
As for having a place where you can put code that will always run when getting a response to the server you could just create an AsyncCallback which has the code in it's onFailure() and onSuccess() methods. Then you can just extend that AsyncCallback everytime you create an AsyncCallback.
public MyAsyncCallback<T> extends AsyncCallback<T>(){
#Override
public void onFailure(Throwable caught){
//Do something
onResponse()
failed(caught);
}
#Override
public void onSuccess(T result){
//Do something
onResponse()
succeeded(result);
}
public void onResponse(){
// Do something or nothing by default
}
public abstract void failed(Throwable caught);
public abstract void succeeded(T result);
};
Whenever you want to create an AsyncCallback just use MyAsyncCallback:
AsyncCallback callback = new MyAsyncCallback(){
#Override
public void failed(Throwable caught){
//Do something
}
#Override
public void succeeded(T result){
//Do something
}
// Optionally override onResponse() if needed
#Override
public void onResponse(){
//Do something
}
}

Whats the best way to invoke a method by Reflection in GWT

What’s the best way to invoke a method by reflection using GWT, I know that there are some frameworks like "GWT Reflection" but I really want to hear some feedback about this.
How is the best way to convert something like this:
GreetingServiceAsync service = GWT.create(GreetingService.class);
AsyncCallback callBack = new AsyncCallback< Void>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(Void result) {
}
};
service.doSomething(callBack);
in:
GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
String methodName = “doSomething”;
Object service;
AsyncCallback callBack = new AsyncCallback< Void>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(Void result) {
}
};
/*somehow invoke by reflection*/
Class<?> c = Class.forName(GreetingServiceAsync.class.getName());
Method method = c.getMethod(methodName, AsyncCallback.class);
method.invoke (service, callBack);
Many thanks,
Luis.
Javascript 101 - there is no concept of reflection. GWT java translates to javascript. So gwt does not provide reflection support. Every other library that states gwt reflection in their homepage are just addressing a corner functionality and mis-stating their feature.

Intercepting Async Proxy Service exceptions for GWT RPC

My app has many RPC calls, and they all have a .onFailure(Throwable caught) method. I have a class shared between the client and the server code NotLoggedInException. This is thrown by the server, if the user doesn't have the relevant permissions based on sessions/cookies/permissions etc.
Ideally I would like to handle this exception in one place BEFORE others are passed to the .onFailure() code, given how ubiquitous this handling is and needs to be for security. There is a GWT.setUncaughtExceptionHandler() but this appears to get called after the handling which isn't ideal (in case an .onFailure accidentally consumes too much).
Does anybody have an elegant solution to this? An ugly solution is to wrap the deferred binded .create() proxy in the same aggregated class implementing the async interface.
Sidenote: The server was issuing a redirect before, but I don't like this paradigm, and would prefer it to be handled by the eventbus of the app.
Update: ugly answer referred to above
public abstract class CustomAsyncCallback implements AsyncCallback{
#Override
public CustomAsyncCallback(AsyncCallback<T> callback)
{
this.wrap = callback ;
}
AsyncCallback<T> wrap ;
#Override
public void onFailure(Throwable caught) {
if (!handleException())
{
wrap.onFailure(caught) ;
}
}
#Override
public void onSuccess(T t) {
wrap.onSuccess(t) ;
}
}
public class WrapDeferredBinding implements RpcInterfaceAsync
{
RpcInterfaceAsync service = GWT.create(RpcInterface.class);
public void method1(int arg1, AsyncCallback<Boolean> callback)
{
service.method1(arg1, new CustomAsyncCallback<Boolean>(callback)) ;
}
public void method2 ....
public void method3 ....
}
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.
Here are the steps to do so:
To begin 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);
}
}
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>
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;
}
}
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?
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));
}
}
Now, your AsyncCallbackProxy can look something like this:
public class AsyncCallbackProxy<T> implements AsyncCallback<T> {
private AsyncCallback<T> delegate;
public AsyncCallbackProxy(AsyncCallback<T> delegate) {
this.delegate = delegate;
}
#Override
public final void onFailure(Throwable caught) {
GWT.log("AsyncCallbackProxy#onFailure() : " + caught.getMessage(), caught);
if (caught instanceof NotLoggedInException) {
// Handle it here
}
delegate.onFailure(proxy);
}
#Override
public final void onSuccess(T result) {
delegate.onSuccess(result);
}
}
References:
DevGuideCodingBasicsDeferred.html
An example applied to performance tracking
You can wrap AsyncCallback class with an abstract class:
public abstract class CustomAsyncCallback<T> implements AsyncCallback<T>{
#Override
public void onFailure(Throwable caught) {
GWT.log(caught.getMessage());
handleException();
this.customOnFailure(yourDesireParam);
}
/**
* this method is optional
*/
public abstract void customOnFailure(Param yourDesireParam);
}
And then send a CustomAsyncCallback object to your RPC asynch methods.

GWT RPC mechanism how to use non void return type

I have a scenario wherein I need to specify a return type to the Synchrnous function, the code is as follows :
#RemoteServiceRelativePath("show_box")
public interface ShowBoxCommandService extends RemoteService{
public ArrayList<String> showBox();
}
The implementation of the method on the server is :
public ArrayList<String> showBox() {
ArrayList<String> box = new ArrayList<String>();
Iterator<Box> boxes = BoxRegistry.getInstance().getBoxes();
while (boxes.hasNext()) {
box.add(boxes.next().toString());
}
return box;
}
I am trying to define the callback variable in the following format at the client side in order to call the method
AsyncCallback<Void> callback = new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
// TODO: Do something with errors.
// console was not started properly
}
#Override
public void onSuccess(Void result) {
// TODO Auto-generated method stub
// dialog saying that the console is started succesfully
}
};
update with the aync interface code :
public interface ShowBoxCommandServiceAsync {
void showBox(AsyncCallback<ArrayList<String>> callback);
}
But this is causing the definition of the method in the Async method to change.
Any ideas or clues will be helpful.
Thanks,
Bhavya
P.S. Apologies if this is a repetition
The callback should be:
AsyncCallback<ArrayList<String>> callback = new AsyncCallback<ArrayList<String>>() {
public void onFailure(Throwable caught) {
// TODO: Do something with errors.
// console was not started properly
}
#Override
public void onSuccess(ArrayList<String> result) {
// TODO Auto-generated method stub
// dialog saying that the console is started succesfully
}
};
If you don't need to utilize the result then you can ignore it, but if that is the case, you should probably question your design and why you would need the method to return an ArrayList<String> in the first place.
If the service interface looks like this:
public interface ShowBoxCommandService extends RemoteService {
public ArrayList<String> showBox();
}
then you must have an associated async interface:
public interface ShowBoxCommandServiceAsync {
public void showBox(AsyncCallback<ArrayList<String>> callback);
}
Which means, that the type of the callback that you should pass to showBox is AsyncCallback<ArrayList<String>>.
new AsyncCallback<ArrayList<String>>() {
#Override
public void onSuccess(ArrayList<String> list) {
// ...
}
#Override
public void onFailure(Throwable caught) {
// ...
}
}
Your callback should not be Void. If your synchronous method returns a List of Strings, the async callback method should receive the List. You'll have to use the ArrayList, because the class needs to implement the Serializable interface.
AsyncCallback<ArrayList<String>> callback = new AsyncCallback<ArrayList<String>>() {
public void onFailure(Throwable caught) {
// TODO: Do something with errors.
// console was not started properly
}
#Override
public void onSuccess(ArrayList<String> result) {
// TODO Auto-generated method stub
// dialog saying that the console is started succesfully
}
};
Huh? Your method returns an ArrayList and you are declaring void in your call?
Change <Void> to <ArrayList<String>>