I want to create a shared class on GWT client and server which uses org.json.* on the server side and com.google.gwt.json.client.*on the client side.
My shared class is something like this:
import org.json.JSONObject;
class SomeDto {
public fromJSON (JSONObject x) }
}
}
This works fine on the server side but on the client side JSONObject should be replaced by com.google.gwt.json.client.JSONObject.
How can I use a shared JSON class on Server and Client, which uses different JSON implementations on client and server?
You have some implementations which work in client and server side:
Elemental Json is an entire implementation in java which works in server and client sides, take a look to its test cases to figure out how it works. It is very light weight and makes use of browser native optimisations in client side.
GwtQuery has a data binding implementation for json objects. It works in both sides and performs very well. Just define an interface extending JsonBuilder and you can share it in server and client. Take a look to this test class to see the usage or to its documentation. BTW gquery uses elemental json in order not to depend on the controversial json.org library.
Finally the classical AutoBeans in GWT is an option to handle JSON and bind it to POJOs. IMO it needs so much boiler-plate code.
Related
I am trying to develop a simple SMTPclient for testing purposes using the SubethaSmtp client package. i want to use the SMTPClient class instead of the SmartClient class for more control but i have not been able to figure out how to write mail data using SMTPClient, the only OutputStream exposed to public or external subclasses is the one for sending commands, the ones for sending data (after sending the DATA command) is exposed only to classes in the same package (SmartClient).
am i missing something here? i would like to know how a direct subclass of SMARTClient can written to work around this problem.
Looks like you are correct, you cannot simply extend the SMTPClient and get access similar to the one that SmartClient has, being a same-package class.
At this point you can either:
1) Fork your own version of the app from https://github.com/voodoodyne/subethasmtp and do whatever the hell you like with it, or
2) Go all the way and implement your own version of SMTPClient, as the package protected SMTPClient.dotTerminatedOutput;, used by SmartClient.dataWrite() actually is just instantiated like so
...
this.rawOutput = this.socket.getOutputStream();
this.dotTerminatedOutput = new DotTerminatedOutputStream(this.rawOutput);
...
Assume that we've some interface my.gwt.shared.Facade in shared package of our GWT project (exists both server and client) and two implementation of it: class my.gwt.client.ClientFacadeImpl (exists only client) and class my.gwt.server.ServerFacadeImpl (exists only server).
Is there any way to write a piece of code or annotation that substitute ClientFacadeImpl in client side and ServerFacadeImpl in server side?
Thanks all for the answers and discussion. I've found simple and elegant solution for my needs.
So, I've interface my.gwt.shared.Facade and two classes: class my.gwt.client.ClientFacadeImpl and class my.gwt.server.ServerFacadeImpl.
interface Facade {
Map<Boolean, Facade> FACADES = new HashMap<Boolean, Facade>();
}
Now, we should fill you FACADES interface. This is done like that:
public class MyEntry implements EntryPoint {
static {
Facade.FACADES.put(true, ClientFacadeImpl.INSTANCE); // client side
}
And
#Startup
#Singleton
public class Initializer {
#PostConstruct
private void init() {
Facade.FACADES.put(false, ServerFacadeImpl.INSTANCE); // server side
// other things
}
}
Now, when I need to get appropriate Facade, I just write
Facade facade = Facade.FACADES.get(GWT.isClient());
Also in this case in map is only corresponding to server or client side implementation.
P. S. Goal of this question was to allow handling of some GwtEvents fired on client direclty on server and vice-versa. This solution removed large set of DTO (data transfer objects) and simplified code a lot.
There's no answer to your question other than "it depends". Or rather, of course there are ways of doing what you ask, but would you accept the tradeoffs?
Given that you tagged the question with dependency-injection, let's start with that. If you use a DI tool with GWT, it's likely GIN (Dagger 2 would work, but it's still under development). In that case, just use distinct modules for GIN client-side and Guice server-side that bind() the appropriate implementation.
For a few releases, GWT.create() can be made to work outside a GWT (client) environment (i.e. on the server side). You have to register a ClassInstantiator on the ServerGwtBridge as an alternative to the rebind rules from gwt;xml files. So you could have a <replace-with class="my.gwt.client.ClientFacadeImpl"> rule in your gwt.xml, and a ClassInstantiator returning a ServerFacadeImpl on the server side.
Finally, you can also use a static factory and replace it with a client-side specific version by way of <super-source>.
A last one, but I'm unsure whether it'd work: you could use an if/else using GWT.isClient(), and annotate your ServerFacadeImpl with #GwtIncompatible to tell the GWT compiler that you know it's not client-compatible.
I'm looking for a communication channel between two java programs running on the same machine. I've found a few options (RMI and XML-RCP) but none of the examples that I found show exchange of objects wich class it's non-primitive and not know on JDK (our own objects).
So, what's the easy technology to use when I want to do this (note that Utils.jar it's on the classpath of Server.jar and Client.jar):
Utils.jar:
class MyClassRequestParams { ... }
class MyClassReturnParams { ... }
Client.jar:
// Server creation
...
// Send request
MyClassRequestParams params = new MyClass...
MyClassReturnParams response = server.send("serverMethodName", params);
Server.jar:
MyClassRequestParams serverMethodName(MyClassRequestParams params)
{
MyClassReturnParams response = new MyC...
// do processing
return response;
}
Just make your transport classes implement the Serializable interface, and everything will be fine with RMI. Note that every object referenced bt the transport object should also be Serializable.
The RMI tutorial uses an example with a custom Task interface implemented by a Pi custom class that is not a "standard" JDK class.
You may also consider Versile Java (I am one of its developers). Follow the link for an example of making remote calls and defining remote interfaces. It implements a platform-independent standard for remote ORB interaction, currently also available for python.
Currently our application uses GWT-RPC for most client-server communication. Where this breaks down is when we need to auto generate images. We generate images based on dozens of parameters so what we do is build large complex urls and via a get request retrieve the dynamically built image.
If we could find a way to serialize Java objects in gwt client code and deserialize it on the server side we could make our urls much easier to work with. Instead of
http://host/page?param1=a¶m2=b¶m3=c....
we could have
http://host/page?object=?JSON/XML/Something Magicical
and on the server just have
new MagicDeserializer.(request.getParameter("object"),AwesomeClass.class);
I do not care what the intermediate format is json/xml/whatever I just really want to be able stop keeping track of manually marshalling/unmarshalling parameters in my gwt client code as well as servlets.
Use AutoBean Framework. What you need is simple and is all here http://code.google.com/p/google-web-toolkit/wiki/AutoBean
I've seen the most success and least amount of code using this library:
https://code.google.com/p/gwtprojsonserializer/
Along with the standard toString() you should have for all Object classes, I also have what's called a toJsonString() inside of each class I want "JSONable". Note, each class must extend JsonSerializable, which comes with the library:
public String toJsonString()
{
Serializer serializer = (Serializer) GWT.create(Serializer.class);
return serializer.serializeToJson(this).toString();
}
To turn the JSON string back into an object, I put a static method inside of the same class, that recreates the class itself:
public static ClassName recreateClassViaJson(String json)
{
Serializer serializer = (Serializer) GWT.create(Serializer.class);
return (ClassName) serializer.deSerialize(json, "full.package.name.ClassName");
}
Very simple!
I know that GWT has a good RPC support. But for various purposes I need to build this on my own:
1.) How can I convert a Bean Object (on the Client Side) like;
class MyPerson {
String name;
String getName();
void setName(String name);
//..
}
with GWT into a JSON String? (Ideally only using libraries that come officially from GWT/Google).
2.) Secondly, how can I send this generated JSON String from the Client side to any Server also using any GWT Client Logik. (Ideally only using libraries that come officially from GWT/Google).
I have searched a lot, but the examples never show how to send data but only to receive JSON data.
Thank you very much!!!
Jens
There's a nifty class called AutoBeanFactory that GWT will create for you, no third-party libs required. See http://google-web-toolkit.googlecode.com/svn-history/r9219/javadoc/2.1/com/google/gwt/editor/client/AutoBeanFactory.html
Once you have your AutoBeanFactory, you can use it like this:
producing JSON from an object of type SimpleInterface
AutoBean<SimpleInterface> bean = beanFactory.create(SimpleInterface.class, simpleInterfaceInstance);
String requestData = AutoBeanCodex.encode(bean).getPayload();
useRequestBuilderToSendRequestWhereverYouWant(requestData);
parsing JSON from an object of type SimpleInterface
SimpleInterface simpleInterfaceInstance = AutoBeanCodex.decode(beanFactory, SimpleInterface.class, responseText).as();
You can use RequestBuilder to send these requests without GWT-RPC or the RF stuff.
I recommend you use RestyGWT it makes JSON rest services work just like GWT RPC services.
Take a look at GWT's AutoBean framework, which can be used to create and receive JSON payloads. The RequestBuilder type can be used to send HTTP requests to the server.
You have also another solution which is 3rd party solution, maybe a second place solution but it can be also the first place.
The 3rd party called GSON and it's a project open source on google code.
You can find it here.
I used it and it's very good and very simple.