GWT - define async services with a subclass of AsyncCallback - gwt

Does GWT allow to define the async services using a custom subclass of AsyncCallback?
Basically, I'd been suggested to do something similar to How to wrap every Callback in one place to improve error handling but do it in a way where the async service is defined using a custom subclass (or rather, a functional interface, with default error handling, as that would allow simple lambda usage).
In other words, when I have
public interface MyService extends RemoteService {
Object doTheThing();
}
I'd like to replace
public interface MyServiceAsync {
void doTheThing(AsyncCallback<Object> callback);
}
with
public interface MyServiceAsync {
void doTheThing(MyCallback<Object> callback);
}
where MyCallback extends AsyncCallback.
This would be done in all the services and anything that needs refactoring would be refactored appropriately.
Currently doing so just produces errors MyServiceAsync is missing method doTheThing(AsyncCallback<Object>) on the class and Last parameter must be of type AsyncCallback on the method.
The question linked at the start is the only thing I could google up, everything else was about normal async service usage.

Related

GWTP REST-Dispatch - What is the new usage for rest dispach, since the removal of the RestService interface in 1.5 release

Hi everybody,
I encounter implementation issues with the rest-dispatch module of the gwtp framework.
If i follow the current documentation, the resource interface defining what a service provide should be as follow:
#Path(FOO)
#Produces(MediaType.APPLICATION_JSON)
public interface FooResource {
#GET
RestAction<FooDTO> getFoo();
}
On the client side (without delegate extension):
#Inject RestDispatch dispatcher;
#Inject FooResource fooResource;
...
dispatcher.execute(fooResource.getFoo(), new AsyncCallback<FooDTO>() {
#Override
public void onFailure(Throwable throwable) {
}
#Override
public void onSuccess(FooDTO fooDto) {
}
});
...
Question
The RestDispatch is waiting for method that return RestAction, but since the RestService interface has been remove from 1.5 release:
How can i implements the FooResource ?
Moreover
In the carstore sample project, the only resource that uses RestAction is:
https://github.com/ArcBees/GWTP-Samples/blob/master/carstore/src/main/java/com/gwtplatform/carstore/shared/api/StatisticsResource.java
But it's implementation, is in fact not an implementation in that case:
https://github.com/ArcBees/GWTP-Samples/blob/master/carstore/src/main/java/com/gwtplatform/carstore/server/api/StatisticsResourceImpl.java
Should i follow this example, and what is the purpose of an non-implemented Interface ?
I assume that my question is very specific and it is maybe principally directed to the authors of gwtp.
And i thank in advance those who will respond.
The rest-dispatch is a client-library, and the interface that describes the services are not to use on the server side.
I was attempting to do something not intended by the authors of GWTP.
Yet, the DelegateResource extension is a solution, if you want to use the interface on the server side too. It comes with a drawback: the anability to have type safe callback on the client side.
To go further, here the exchange i had with the team on github:
https://github.com/ArcBees/GWTP-Samples/issues/92

How to do XSS escaping on input coming into Restlet web service

I have a GWT web application using Restlet.
It has #Post annotated service methods that take a bean and perform some logic on it.
I want to XML-escape the data in these beans.
For example, say I have the following:
public class MyService extends ServerResource {
#Post
public DataBean performLogic(DataBean bean) {
...
}
}
public class DataBean {
String data;
}
Is there a way I could XML-escape DataBean.data after it's serialized but before it is sent to MyService.performLogic()?
You can override the doInit() method, this may allow you do do what you need; but will occur before any calls to your #Post #Get method in your ServerResource.
Alternatively if you need it more widely you may want to look at adding a Filter into your Command Chain and overriding the beforeHandle() method there.

Serialization Exception while making an RPC call

I have created a very basic application. I have only one service class and a corresponding Async class which contains only Java types and no custom classes. But still I get the serialization exception.
My service class looks like this.
public interface MyService extends RemoteService {
public String getName();
public Object getAdditionalDetials(ArrayList<String> ids);
public Date getJoiningDate();
}
My async interface looks like this
public interface MyServiceAsync {
public void getName(AsyncCallback<String> callback);
public void getAdditionalDetials(ArrayList<String> ids, AsyncCallback<Object> callback);
public void getJoiningDate(AsyncCallback<Date> callback);
}
I know I am making some stupid mistake.
I am Naive in gwt rpc and serialization mechanism, but will try to answer your question.
Whenever you write classes involving an RPC, GWT creates a Serialization Policy File. The serialization policy file contains a whitelist of allowed types which may be serialized.
In your Service methods, all the types you mention and refer will be automatically added to this list if they implements IsSerializable. In your case you have used the following two methods,
public String getName();
public Date getJoiningDate();
Here you have used String and Date as your return types and hence it is added to your Serialization Policy File. But in the below method their lies a problem,
public Object getAdditionalDetials(Arraylist<String> ids);
Here you have used ArrayList and String that is not a problem and they will be added to your whitelist, but the problem is you have mentioned return type as Object. Here GWT Compiler does not know what type to be added to whitelist or Serialization Policy and hence it wont pass your RPC call. The solution is use mention a class which implements IsSerializable instead of mentioning the return type of type Object.
FWIW, I was having this problem but my 'Object' type was hidden behind generified classes.
So if one of your rpc methods involves a class:
class Xxx<T> implements IsSerializable {...
It needs to change to:
class Xxx<T extends IsSerializable> implements IsSerializable {...

Failure at loading GWT library

I am trying to deploy a bigger GWT project to start working on it. After several problems I finally ran into the following, which I am not able to solve:
Here is a random piece of code:
service.getSuggestionOracle(this.suggestionString.getText(), new AsyncCallback<List<Entity>>() {
#Override
public void onSuccess(List<Entity> result) {
suggestionString.setStyleName("searchInput");
processSuggestionOracle(result);
}
#Override
public void onFailure(Throwable caught) {
suggestionString.setStyleName("searchInput");
GWT.log("Suggestion fails.");
}
});
Eclipse complains about the two functions onSuccess and onFailure that:
The method onSuccess(List<Entity>) of type new AsyncCallback<List<Entity>>(){} must override a superclass method
Indeed when I hover over the: new AsyncCallback<List<Entity>>() statement, it tells me that If an RPC is successful, then onSuccess(Object) is called, otherwise onFailure(Throwable) is called.
I conclude that there IS a superclasses with declarations for onSuccess and onFailure, but the compiler doesn't find it.
I use GWT-2.4.0 and the GWT library is added to the classpath.
The code above is just a random example, there are about 150 similar errors all over the
project. Additionally, there are several imports like com.xind.gwt.dom.client.DOM,
that can not be resolved.
Does anybody have an idea what I am missing here?
There are two possibilities that I could think of:
you haven't extended RemoteServiceServlet on the server implementation.
or
In this code,
public void onSuccess(List result) {
}
you have List as the returned object. Is this a list of objects of a user-defined class or java datatype? If the list is a user-defined type, then you must serialize the corresponding class by implementing java.io.serializable;

GWT RequestFactory and multiple types

My GWT app has ten different kinds of entities. Right now I use plain old DTOs and transport them over GWT-RPC. This works well for cases like startup - I can pack them all into a single request.
I'm looking at switching to RequestFactory because there are many times throughout the lifetime of the app (30 minutes, on average) when I just have to update one type of entity, and the unifying/bandwidth-saving features of RequestFactory are appealing. BUT: I don't see a way to download all of my initialization data in a single request when the app loads. I don't want to have to make ten requests to fetch all of the init data for my ten entity types.
Is there a way to make a GeneralRequestContext, or something? I'd even be happy with a solution like:
public interface InitDataProxy extends EntityProxy
{
public UserProxy getInitUsers();
public OrganizationProxy getInitOrganizations();
...
}
public interface GeneralRequestContext extends RequestContext
{
Request<InitDataProxy> getInitData();
}
But this won't work because I don't want to have to actually back InitDataProxy with anything, I just want to use it to combine a bunch of different types of Proxies in a single request.
So: Is there a way to receive multiple, unrelated types of EntityProxy in a single request?
I would also be happy enough making a normal gwt-rpc request to go outside of RequestFactory for this data, but I don't want to have to implement duplicate DTOs to run next to RequestFactory's proxies, and write custom code to copy the DTOs into them!
The InitDataProxy could extend ValueProxy instead, which doesn't require that the object on the server have any kind of id or version semantics. The domain-side InitData type could be an interface, possibly implemented with an anonymous type.
interface InitData {
User getUser();
Organization getOrgatization();
}
class InitService {
static InitData makeInitData() {
return new InitData() { ..... };
}
}
#ProxyFor(InitData.class)
interface InitDataProxy extends ValueProxy {
UserProxy getUser();
OrganizationProxy getOrganization();
}
#Service(InitService.class)
interface Init extends RequestContext {
Request<InitDataProxy> makeInitData();
}