-
6 May 2012 8:54 PM #1
Facing problem in JSON encoding and decoding using DirectJNgine
Facing problem in JSON encoding and decoding using DirectJNgine
Hi,
We are evaluating DirectJNgine for server side stack for ExtJs 4.1 and we are not able to find answers of following queries in case of Json encoding decoding by using DJN:- When we actually need to write our own Json encoding decoding code while we can easily use Ext.Data.DirectStore for directly sending client side data to server side and vice-a-versa.
- Is it necessary to write inner static class for serialization and deserialization for each of the complex object like UserDetail object in subclass of DefaultGsonBuilderConfigurator.java.
- Is it needed to write serialization-deserialization logic in inner static classes of the class that is subclass of the DefaultGsonBuilderConfigurator.java or we can write these logic in non static inner classes.
- Suppose we have written separate inner static classes for serialization and deserialization of two objects like Date and UserDetail and using these inner static classes in configure() method as follows:
And now in one of my request to server, I want to execute only date serilization and in other request I want to execute only UserDetail serialization. So, how it can be done? Should we have to use some if-else like conditions or DirectJNgine provides some built-in functionality to handle this type of situation?Code:builder.registerTypeAdapter( Date.class, new JsonDateSerializer() ); builder.registerTypeAdapter( UserDetail.class, new JsonUserDetailSerializer() );
-
14 May 2012 1:28 AM #2
You should *very* rarely need to write custom encoders/decoders, DJN takes care of everything 99% of the time.
You might want to do that to handle things such as Dates. Dates are not a first-class type in JSON, so you must decide how they will be handled, and write your encoders/decoders accordingly. While DJN might impose a format, I choose to be neutral and not to impose a format to DJN users.Pedro Agulló, Barcelona (Spain)
Agile team building, consulting, training & development
DirectJNgine: http://code.google.com/p/directjngine - Log4js-ext: http://www.softwarementors.com/projects/p/log4js-ext/
-
15 May 2012 12:21 AM #3
But manual serialization - deserialization needed in case of complex object in DJN
But manual serialization - deserialization needed in case of complex object in DJN
On the basis of your statement as follows:
I have tested serialization and deserialization between json and java with some complex json object, but I found that it was not done automatically and I have to write code by iterating json object and assigning corresponding values to java object. Followings are the codes:You should *very* rarely need to write custom encoders/decoders, DJN takes care of everything 99% of the time.
Javascript code:Now the json object is having a company list and each company has a manager object and a list of employee object. following are my java classes:Code:Ext.onReady(function(){ var aDate = {year: 2005, month: 3, day: 20}; var userJson = {name: 'Jitendra', age: 3, city: 'Delhi'}; var companies = [ { "id": "17", "name": "Emkay Entertainments", "address": "Nobel House, Regent Centre", "manager": { "firstName": "John", "lastName": "Doe" }, "employees": [ { "firstName": "Brian", "lastName": "Hunt" }, { "firstName": "Mick", "lastName": "Henning" } ] }, { "id": "18", "name": "The Empire", "address": "Milton Keynes Leisure Plaza", "manager": { "firstName": "Ana", "lastName": "Johnsnon" }, "employees": [ { "firstName": "Erick", "lastName": "O'Neil" }, { "firstName": "George", "lastName": "Halloway" } ] } ]; Ext.Direct.addProvider( Ext.app.REMOTING_API ); //testing with custom hierarchical json object for serialization and deserialization CompanyAction.getCompanyDetail(companies, function(result, e) { var t = e.getTransaction(); alert(result.name); }); CompanyAction.test("jks",null, function(result, e) { var t = e.getTransaction(); }); });
1) CompanyAction.java --- exposed java class
2) Company.javaCode:package company; import java.util.ArrayList; import com.softwarementors.extjs.djn.config.annotations.DirectMethod; public class CompanyAction { @DirectMethod public ArrayList<Company> getCompanyDetail(ArrayList<Company> companies){ if(companies.size()>0) System.out.println("company name = "+companies.get(0).getName()); return companies; } @DirectMethod public String test(String a, String b){ return "tested"; } }
// code for some getters and settersCode:package company; import java.util.ArrayList; public class Company { private String id; private String name; private String address; private Manager manager; private ArrayList<Employee> employees;
}
3) Employee.java
4) Manager.javaCode:package company; public class Employee { private String firstName; private String lastName; //code for getters and setters }
Now, I have read your document and also done a lot of googling, but I didn't find any type of configuration between Json object attributes and Java class attributes in DJN so that the values of Json object attributes can be directly assigned to corresponding java class attributes. How does the DJN control will automatically decide that the value of first name of Manager attribute of Json object will be assigned to the First Name of Manager Java Object but not to that of Employee Java Object. I have done this by manually writing serialization deserialization code, but in DWR it can be done automatically by just some configurationCode:package company; public class Manager { private String firstName; private String lastName; //code for getters and setters }
Actually, this issue has become a bottleneck in our evaluation process and due to this some of our team members are suggesting DWR as alternate solution.
So, please if there is any configuration based approach or annotation based approch to solve this issue, then suggest me.
-
15 May 2012 5:13 AM #4
When it comes to serialization/deserialization and all json handling, GSON is THE library in charge of it all: that's the one you should become familiar with. You will want to take a look at the documentation in http://sites.google.com/site/gson/gson-user-guide to use DJN beyond trivial scenarios.
The issue you are experiencing is related to you using generic collections (that List). There is a problem with Java generics and type erasure that hinders GSon (very clearly explained in their doc, you'll want to take a look at it). I usually walk around this problem by recommending to use arrays as much as possible in the DTOs that move things to/from your business layer to the UI layer (Javascript), as they do not suffer from the limitations of generic collections.
With respect to how to control what fields are serialized/deserialized, look for ''transient', @Expose' and 'ExclusionStrategy' in that document: you'll find that you have absolute control over serialization.
If you plan to bypass DTOs and want to move business objects up and down via json you'll find other issues that will bite you, beyond the generics collections one. These issues include handling polymorphism at the client level, or controlling when to stop serialization of the business model so that you do not pull the whole object structure from your app and send it to the client.
Using DTOs is not that bad of an idea because they clearly delineate what and what is not transferred, and allows one to embed contextual information that you simply can't pass as part of the business objects.
To skip intermediate DTOs there might be a need to find a good solution for handling those issues without contaminating your business objects. I know because I have collaborated to develop such a thing with some customers.
Of course this is not a 'one size fits all' thing, whether using DTOs, business objects 'as-is' or devising some smart way to handle business object makes sense, depends on the kind of app you are developing.
RegardsPedro Agulló, Barcelona (Spain)
Agile team building, consulting, training & development
DirectJNgine: http://code.google.com/p/directjngine - Log4js-ext: http://www.softwarementors.com/projects/p/log4js-ext/
-
16 May 2012 8:36 PM #5
Hi Pagullo,
Thank you very much for your quick response. it is very helpful for me and following your idea like, I solved the above problem.I am giving here the changes that I have done to solve above problem, so that others can take advantage of it:The issue you are experiencing is related to you using generic collections (that List). There is a problem with Java generics and type erasure that hinders GSon (very clearly explained in their doc, you'll want to take a look at it).
1) CompanyAction.java ---- Our exposed class
2) Company.javaCode:package company; import java.util.ArrayList; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.annotations.Expose; import com.softwarementors.extjs.djn.config.annotations.DirectMethod; public class CompanyAction { @DirectMethod public Company[] getCompanyDetail(Company[] companies) { return companies; } @DirectMethod public Companies test(){ return new Demo1().getEmployeeInfo(); } }
The changes that i have done is, I am now passing a company array as a parameter in getCompanyDetail() method of CompanyAction.java and also changes the datatype of employees in Company class to company array instead of ArrayList<Company>. And, now its working fine and data from Json from clientside are automatically mapped to corresponding attributes of Company class. And, the best part is that I haven't written a single line of code manually for this serialization and deserialization process.Code:package company; import java.util.ArrayList; public class Company { public String id; public String name; public String address; public Manager manager; public Employee[] employees; }


Reply With Quote