Still wresting with GWT and App Engine, and I have come to this problem:
I have an app engine populated with va开发者_Go百科rious data, which I would like to present on the client using a GWT RPC.
I have found out the hard way that, because my Model objects are annotated with JDO, i can't just send them back to the client because they aren't serializable. This means I'm going to have to create a layer of intermediate classes to extract data from my model objects, and send it back to the client to use asynchronously.
I am wondering though, it is possible to construct a GWT object in a servlet and send it back to be used? For example, the servlet would be receive my asynchronous request, pull out the data i want from the database, create a GWT VerticalPanel() with appropriate child elements for the data, and send that VerticalPanel back to the client to be injected.
My understanding of the Java / Javascript interaction that is going on here is still foggy, and I'm thinking that sending a Java object that is not compiled to Javascript after the application is deplyed will not work. Can anybody clarify this for me?
No the server can't create GWT UI objects (like vertical panels) to be used in the presentation layer, nor should it, that's why it's called a 'server' and a 'presentation layer' one serves the data and handles all the business logic, the other displays things on a screen and allows a user to interact with them.
You can however send your JPA annotated POJO's to the front end just fine (we do it in all our applications). You simply need to include the source code for the annotations themselves so that GWT knows how to compile them. You also need to make sure your POJOs's are in a package that is referenced by a NameOfXmlFile.gwt.xml file, eg:
<module>
<inherits name='com.google.gwt.user.User'/>
<source path="domain" />
</module>
This file in my case is in a folder above a package called 'domain' where all my JPA annotated POJO's live. Then in your client side you tell it to inherit that .gwt.xml file:
<module>
<inherits name='com.google.gwt.user.User'/>
<!-- Domain layer references -->
<inherits name='your.package.structure.NameOfXmlFile'/>
</module>
There are restrictions on what you can put in those classes (like for example BigDecimal is not supported, etc) but anything that can be compiled by the GWT compiler (and JPA annotations certainly can be) can be sent without needing any kind of transfer objects. This is one of the real strengths of GWT, that you can use the same JPA Pojos in your entire application, without ever needing to create any other similar object.
Edit: I just noticed you said JDO and not JPA. I assume the same applies there as well though if they are just annotations?
I've seen good answers, so I won't repeat them myself..
Anyway my simple but vital suggestion is: the only way to go is through POJO objects.. BUT IMHO to avoid problems, remember that your POJO objects SHOULD be really PLAIN
Anyway, I can suggest you also a little framework I recently did (few hours of work, so don't expect a rocket!).
It is pojo-injector: http://code.google.com/p/pojo-injector
It helps you in translating your data models to POJO and back... It's based on annotations (only on the POJO side!).
I hope it can help.
This is (imho) one of the problems with GWT.
Basically in Java Web applications it's pretty common to have data or domain objects (which would be your JDO objects) and presentation objects, which are sent to the view. Some go much further than this and can have many more layers of abstraction ("go ahead, add one more layer").
I can see the argument for this but it adds a lot of boilerplate as you translate objects between layers.
Anyway, in GWT you need to do this if your domain objects are POJOs (and as with JPA, even though they claim to be POJOs, the annotations make them not so in reality).
GWT will do this for you on objects returned by your RPC interface but there are certain classes you can't use (eg BigDecimal) as there is no Javascript equivalent (so to use BigDecimals you pass Strings around to construct BigDecimals yourself on the serverside when you ened them and convert them back to Strings when you send them to the client).
精彩评论