GWT + EJB + MYSQL - mysql

I have got some Question concerning Serialization and persistence.
At First I have got a GWT project with Client code and a Servlet to communicate with
my EJB Project.
In the EJB project there are some Persistent Entitie Classes with references among each other and beans to manage them.
The Reference may look like this:
Object A
/ \
Object B Object C
\
Object D
Mostly there are 1:n Relationships, which i have to modelling with oneToMany or something like this..
I store them into a MYSQL Database which already work with Strings.
With Strings I haven't got Problems to transfer them from the GWT Client Side over the GWt Servlet to the EJB Bean and then into the Database and the same way back to the Client Side.
But when I try to transfer an own created Class object (POJO?) between GWT Client and EJB, I always get an Serialization Exception.
Is it because of the GWT Servlet? I read something that you have to use DTo or Value Objects? Is this correct?
or isn't there a easy way to solve this?

Please see
http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html#DevGuideSerializableTypes
All classes that conform to the above specification
or implement com.google.gwt.user.client.rpc.IsSerializable can be serialized.
For example:
import com.google.gwt.user.client.rpc.IsSerializable;
import java.util.HashMap;
public class Row implements IsSerializable
{
private HashMap _row;
public Row()
{
_row = new HashMap();
}
public Row(HashMap row)
{
_row = row;
}
public Object getCellValue(String columnName)
{
return _row.get(columnName);
}
public void setCellValue(String columnName, Object value)
{
_row.put(columnName, value);
}
public HashMap getRow()
{
return _row;
}
}
In the documentation there is also the link below, I've never tried that
http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html#DevGuideCustomSerialization

Related

Spring MVC Test, MockMVC: Conveniently convert objects to/from JSON

I am used to JAX-RS and would like to have similar comfort when sending requests using Spring MVC and working with the responses, i.e. on the client side inside my tests.
On the server (controller) side I'm quite happy with the automatic conversion, i.e. it suffices to just return an object instance and have JSON in the resulting HTTP response sent to the client.
Could you tell me how to work around the manual process of converting objectInstance to jsonString or vice versa in these snippets? If possible, I'd also like to skip configuring the content type manually.
String jsonStringRequest = objectMapper.writeValueAsString(objectInstance);
ResultActions resultActions = mockMvc.perform(post(PATH)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonStringRequest)
)
String jsonStringResponse = resultActions.andReturn().getResponse().getContentAsString();
Some objectInstanceResponse = objectMapper.readValue(jsonStringResponse, Some.class);
For comparison, with JAX-RS client API I can easily send an object using request.post(Entity.entity(objectInstance, MediaType.APPLICATION_JSON_TYPE) and read the response using response.readEntity(Some.class);
if you have lot's of response objects, you could create some generic JsonToObject mapper-factory. It could be then used to detect the object type from a generic response (all response objects inherit from the same generic class) and respond/log properly from a bad mapping attempt.
I do not have a code example at hand, but as a pseudocode:
public abstract GenericResponse {
public String responseClassName = null;
// get/set
}
In the server code, add the name of the actual response object to this class.
The JsonToObject factory
public ConverterFactory<T> {
private T objectType;
public ConverterFactory(T type) {
objectType = type;
}
public T convert(String jsonString) {
// Type check
GenericResponse genResp = mapper.readValue(result.getResponse().getContentAsString(),
GenericResponse.class);
if (objectType.getClass().getSimpleName().equals(genResp.getResponseClassName())) {
// ObjectMapper code
return mapper.readValue(result.getResponse().getContentAsString(),
objectType.class);
} else {
// Error handling
}
}
}
I think this could be extended to be used with annotation to do more automation magic with the response. (start checking with BeanPostProcessor)
#Component
public class AnnotationWorker implements BeanPostProcessor {
#Override
public Object postProcessBeforeInitialization(final Object bean, String name) throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(), field -> {
// make the field accessible if defined private
ReflectionUtils.makeAccessible(field);
if (field.getAnnotation(MyAnnotation.class) != null) {
field.set(bean, log);
}
});
return bean;
}
}
The above code snippet is copied from my current project and it injects to fields, you need to change it so, that it works for methods, eg ... where you may need it.
Having this all implemented may be tricky and can't say it necessarily works even, but it's something to try if you don't mind a bit of educative work.

Grails 3 deep JSON marshaller

I've defined and registered some custom marshallers for my domain objects. If used alone, just rendering one instance, works fine, but the problem comes when I return a map with an array of those instances. In this moment my custom marshaller is not beign invoked.
This is one of my marshallers:
class BackendCompanyMarshaller implements ObjectMarshaller<JSON> {
#Override
public boolean supports(Object object) {
object instanceof Company
}
#Override
public void marshalObject(Object object, JSON converter)
throws ConverterException {
JSONWriter writer = converter.getWriter()
writer.object()
writer.key('id').value(object.id)
.key('name').value(object.name?.encodeAsHTML()?:'')
.key('description').value(object.description?.encodeAsHTML()?:'')
.key('enterprise').value(object.enterprise?.encodeAsHTML()?:'')
writer.endObject()
}
}
Ans for example this is what I'm returning from my controller:
render text:[achievements:arrayOfAchievements, total:2] as JSON
In previous versions of grails I know there was deep marshallers but I haven't been able to find something similar for grails 3.
I have also tried to implement a custom marshaller for List, but I'm not sure what I should return or write.

Handel JSON of different type in Spring POST request

I keep getting Bad request 400 when trying to POST this array of JSON objects "sorry bad format":
{
"type":"input","uniqueId":434,"label":"name","viewToCall":"input-configuration-menu"},{"type":"button","uniqueId":930,"label":"name","viewToCall":"button-configuration-menu"}]
Im not sure how to handel different type of json object in my #Requestbody:
#RequestMapping(value="/saveForm", method = RequestMethod.POST)
public #ResponseBody void saveForm( #RequestBody ArrayList<Components> text ){
do somthing...
}
I found this resourcer but I dont have the experience to get it to work i n web environment:
Spring #RequestBody containing a list of different types (but same interface)
http://programmerbruce.blogspot.com.es/2011/05/deserialize-json-with-jackson-into.html
http://aredko.blogspot.se/2012/04/json-for-polymorhic-java-object.html
There is a missing [ at the beginning of the JSON, otherwise it's valid JSON. If the problem is not the missing angle bracket, put the logs in DEBUG or TRACE, and post the stacktrace.
Also the components need to be annotated with something like this, in order for Jackson to know which object need to be instantiated (see also Jackson polymorphism without annotations):
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=As.WRAPPER_OBJECT)
#JsonSubTypes({
#Type(value=Input.class, value="input"),
#Type(value=Button.class, value="button")})
public interface Component {
...
}
#JsonTypeName("type")
public Sub1 implements Component {
}
#JsonTypeName("button")
public Button implements Component {
}

Does Spring Support JSON Configuration?

Does anyone know if Spring has any extensions that allow for configuring its ApplicationContext via JSON (or really any other format) rather than XML? I couldn't find anything in the official docs, but I was wondering if there were any other open source extensions that could allow this.
Just to be clear, I'm not talking about configuring SpringMVC to set up a RESTful JSON-based web service or anything like that, just if it's possible to do Spring app configuration via JSON instead of XML.
As far as I know there is no project to support JSON as configuration source. It should be relatively easy to kick-start, (Spring container has no dependency on XML, it is just a way to construct bean definitions). However it is much more work than you might think.
Note that Spring provides xml-schema to assist you in writing correct XML. You won't get that much in JSON. Also many DSLs were built on top of Spring XML and custom namespaces support (spring-integration, mule-esb and others use it).
If you hate XML (many do), try out Java Configuration, available since 3.0 and improved in 3.1:
#Configuration
public class MyBeans {
#Bean
public Foo foo() {
return new Foo();
}
#Bean
public Bar bar() {
return new Bar(foo());
}
#Bean
public Buzz buzz() {
Buzz buzz = new Buzz();
buzz.setFoo(foo());
return buzz;
}
}
Interesting fact: thanks to some fancy proxying, foo() is called exactly once here, even though referenced twice.
Try JSConf library available on maven central, it's support Properties, HOCON and JSON format.
You can inject values from external file to your service and more !
Sample usage of JavaConfig :
You data stored on file app.conf
{
"root":{
"simpleConf":{
"url":"Hello World",
"port":12,
"aMap":{
"key1":"value1",
"key2":"value2"
},
"aList":[
"value1",
"value2"
]
}}
You service where your configuration must be inject
#Service("service")
public class Service {
#Autowired
private ConfigBean configBean;
}
Declare a interface to access your configuration values from your service
#ConfigurationProperties("root/simpleConf")
public interface ConfigBean {
String getUrl();
int getPort();
Map getAMap();
List getAList();
}
And your Spring configuration bean :
#Configuration
public class ContextConfiguration {
#Bean
public static ConfigurationFactory configurationFactory() {
return new ConfigurationFactory().withResourceName("app.conf") //
.withScanPackage("org.jsconf.core.sample.bean");
}
}

How can I pass complex objects as arguments to a RESTful service?

I have successfully set up a quick test of creating a "REST-like" service that returns an object serialized to JSON, and that was quite easy and quick (based on this article).
But while returning JSON-ified objects was easy as peach, I have yet to see any examples dealing with input parameters that are not primitives. How can I pass in a complex object as an argument? I am using Apache CXF, but examples using other frameworks like Jackson are welcome too :)
Client side would probably be something like building a javascript object, pass it into JSON.stringify(complexObj), and pass that string as one of the parameters.
The service would probably look something like this
#Service("myService")
class RestService {
#GET
#Produces("application/json")
#Path("/fooBar")
public Result fooBar(#QueryParam("foo") double foo, #QueryParam("bar") double bar,
#QueryParam("object") MyComplex object) throws WebServiceException {
...
}
}
Sending serialized objects as parameters would probably quickly touch the 2KB URL-limit imposed by Internet Explorer. Would you recommend using POST in these cases, and would I need to change much in the function definitions?
After digging a bit I quickly found out there are basically two options:
Option 1
You pass a "wrapper object" containing all the other parameters to the service. You might need to annotate this wrapper class with JAXB annotations like #XmlRootElement in order for this to work with the Jettison based provider, but if you use Jackson in stead there is no need. Just set the content type to the right type and the right message body reader will be invoked.
This will only work for POST type services of course (AFAIK).
Example
This is just an example of turning the service mentioned in the original question into one using a wrapper object.
#Service("myService")
class RestService {
#POST
#Produces("application/json")
#Path("/fooBar")
public Result fooBar(
/**
* Using "" will inject all form params directly into a ParamsWrapper
* #see http://cxf.apache.org/docs/jax-rs-basics.html
*/
#FormParam("") FooBarParamsWrapper wrapper
) throws WebServiceException {
doSomething(wrapper.foo);
}
}
class ParamsWrapper {
double foo, bar;
MyComplexObject object;
}
Option 2
You can provide some special string format that you pack your objects into and then implement either a constructor taking a string, a static valueOf(String s) or a static fromString(String s) in the class that will take this string and create an object from it. Or quite similar, create a ParameterHandler that does exactly the same.
AFAIK, only the second version will allow you to call your services from a browser using JSONP (since JSONP is a trick restricted to GET). I chose this route to be able to pass arrays of complex objects in the URI.
As an example of how this works, take the following domain class and service
Example
#GET
#Path("myService")
public void myService(#QueryParam("a") MyClass [] myVals) {
//do something
}
class MyClass {
public int foo;
public int bar;
/** Deserializes an Object of class MyClass from its JSON representation */
public static MyClass fromString(String jsonRepresentation) {
ObjectMapper mapper = new ObjectMapper(); //Jackson's JSON marshaller
MyClass o= null;
try {
o = mapper.readValue(jsonRepresentation, MyClass.class );
} catch (IOException e) {
throw new WebApplicationException()
}
return o;
}
}
A URI http://my-server.com/myService?a={"foo":1, "bar":2}&a={"foo":100, "bar":200} would in this case be deserialized into an array composed of two MyClass objects.
2019 comment:
Seeing that this answer still gets some hits in 2019, I feel I should comment. In hindsight, I would not recomment option 2, as going through these steps just to be able to be able to do GET calls adds complexity that's probably not worth it. If your service takes such complex input, you will probably not be able to utilize client side caching anyway, due to the number of permutations of your input. I'd just go for configuring proper Cross-Origin-Sharing (CORS) headers on the server and POST the input. Then focus on caching whatever you can on the server.
The accepted answer is missing #BeanParam. See
https://docs.jboss.org/resteasy/docs/3.0-rc-1/javadocs/javax/ws/rs/BeanParam.html
for further details. It allows you to define query params inside a wrapper object.
E.g.
public class TestPOJO {
#QueryParam("someQueryParam")
private boolean someQueryParam;
public boolean isSomeQueryParam() {
return someQueryParam;
}
public boolean setSomeQueryParam(boolean value) {
this.someQueryParam = value;
}
}
... // inside the Resource class
#GET
#Path("test")
public Response getTest(#BeanParam TestPOJO testPOJO) {
...
}
the best and simplest solution is to send your object as a json string and in server side implement a method which will decode that json and map to the specified object as per your need.. and yes it`s better to use POST.