Code in the last
I personally do not like HTTP and JSON, may be the cause of the game, the communication protocol and communication mode is very sensitive, so even for the application I will choose RPC instead of HTTP, but sometimes for various reasons, still do not handle the standard http+json things.
This time you do have to deal with a whole bunch of JSON, which translates a whole bunch of JSON into standard Java Pojo. Maybe a little json string we can just use Jsonobject to get a value, but if JSON is:
A pojo with nearly hundred different fields, if we need to go to the value of a separate estimate will be crazy, this is not the main, the more the egg is the Pojo itself is the property of the array or other Pojo, in turn nested, it is estimated that I am crazy. Another problem is that if the name of the field is modified, the name of the get is changed manually, and it is totally menial work.
(PS: The above figure, is the value returned by Nutch+es, I have made a search engine to play, all return to have big tuo of data, but I actually deal with this data is not, here just use it for example, their own search engine in:
http://search.bucry.com/is purely for fun.)
But I have to face this problem, is to make this a large string of JSON into Pojo, so I naturally think of lazy, want to use a thing automatically encapsulated it into Pojo, automatically identify the field of Pojo, automatically from the JSON to fetch, and automatically call set assignment, even if the field name is changed later, And what? It does not matter, it is reflection, so start to do, I need to solve the problem as follows:
1. Iterate over the properties of the Pojo and get the name of the variable that gets its properties
2. According to the name of the property, get the value from the Jsonobject
3. The jsonobject inside the get value is required to know the type of the variable, if it is a pojo, then continue the recursive call Walk 1
4. When the jsonobject inside the get value if it is a list alive array then use Jsonarray, then take the value by string, then judge String, recursive walk 2
5. Reflection Call Set Method assignment
6. Packaging success
To solve the above problem, the first thing I think of is reflection, but reflection in the reflection of it must know the class full path, so I have its limitations:
The Pojo class must have this field:
Private String className = Rowresponse. class. GetName ();
That is, when the server Tojson this field to the client, the client is sent intact to the server, then it can be successfully automatically encapsulated by recursion all the Pojo, some people will say that so many a field data volume will increase, will make communication slow, here I want to say is, JSON is so large that I need to deal with the Pojo, but also the speed of the eggs, this big lump of things doomed it will not be fast.
First we must have two methods, one dealing with jsonobject, the other dealing with Jsonarray, and then they cross-call each other, and they will call each other recursively :
PublicObject Translatefromjson (Jsonobject jsonobject)throwsException {jsontype Jsontype=Jsontype.jsonobject; Class<?> BaseClass = Class.forName (jsonobject.getstring ("ClassName")); Object Object=baseclass.newinstance (); Field[] Fields=Baseclass.getdeclaredfields (); for(Field filed:fields) {Class<?> Filedtype =Filed.gettype (); Object Filedvalue=NULL; if("Serialversionuid". Equals (Filed.getname ())) { Continue; } if(Filedtype.getcanonicalname (). Contains ("int") | | filedtype.getcanonicalname (). Contains ("Integer") ) {Filedvalue=Jsonobject.getint (Filed.getname ()); } Else if(Filedtype.getcanonicalname (). Contains ("String") ) {Filedvalue=jsonobject.getstring (Filed.getname ()); } Else if(Filedtype.getcanonicalname (). Contains ("List") ) {Jsontype=Jsontype.jsonarray; Filedvalue=Jsonobject.getjsonarray (Filed.getname ()); } Else if(Filedtype.getcanonicalname (). Contains ("Long") | | filedtype.getcanonicalname (). Contains ("Long")) ) {Filedvalue=Jsonobject.getlong (Filed.getname ()); } Else if(Filedtype.getcanonicalname (). Contains ("Double") | | filedtype.getcanonicalname (). Contains ("Double") ) {Filedvalue=jsonobject.getdouble (Filed.getname ()); } Else if(Filedtype.getcanonicalname (). Contains ("Boolean") | | filedtype.getcanonicalname (). Contains ("Boolean") ) {Filedvalue=Jsonobject.getboolean (Filed.getname ()); } Else{Jsontype=Jsontype.jsonobject; Filedvalue=Jsonobject.getjsonobject (Filed.getname ()); } if(Filedvalue = =NULL|| Filedvalue.tostring (). Length () = = 0) { Continue; } if(!filedvalue.tostring (). Contains ("[{") &&!filedvalue.tostring (). Contains ("]}") &&! Filedvalue.tostring (). Contains ("ClassName") ) {String Firstmethodnamechar= Filed.getname (). substring (0, 1); String MethodName= "Set" + firstmethodnamechar.touppercase () + filed.getname (). SUBSTRING (1, Filed.getname (). Length ()); Method Method=Baseclass.getmethod (MethodName, Filed.gettype ()); Method.invoke (object, Filedvalue); } Else if(Filedvalue.tostring (). Contains ("ClassName") {Object Subclassobject=NULL; Switch(jsontype) { CaseJsonarray:subclassobject=Translatefromjson ((Jsonarray) filedvalue); Break; CaseJsonobject:subclassobject=Translatefromjson ((jsonobject) filedvalue); Break; } String Firstmethodnamechar= Filed.getname (). substring (0, 1); String MethodName= "Set" + firstmethodnamechar.touppercase () + filed.getname (). SUBSTRING (1, Filed.getname (). Length ()); Method Method=Baseclass.getmethod (MethodName, Filed.gettype ()); Method.invoke (object, Subclassobject); } Else{Object Subclassobject=NULL; Switch(jsontype) { CaseJsonarray:subclassobject=Translatefromjson ((Jsonarray) filedvalue); Break; CaseJsonobject:subclassobject=Translatefromjson ((jsonobject) filedvalue); Break; } String Firstmethodnamechar= Filed.getname (). substring (0, 1); String MethodName= "Set" + firstmethodnamechar.touppercase () + filed.getname (). SUBSTRING (1, Filed.getname (). Length ()); Method Method=Baseclass.getmethod (MethodName, Filed.gettype ()); Method.invoke (object, Subclassobject); } } returnobject; }
PublicObject Translatefromjson (Jsonarray jsonobject)throwsException {List<Object> outputstringlist =NewLinkedlist<object>(); for(inti=0; I<jsonobject.length (); i++) {String Filedvalue=Jsonobject.get (i). toString (); if(Filedvalue.contains ("ClassName") {jsonobject JsonObject1=NewJsonobject (Filedvalue); Outputstringlist.add (Translatefromjson (JsonObject1)); } Else{outputstringlist.add (filedvalue); } } returnoutputstringlist; }
The process is as follows:
1. According to ClassName reflects an example of this class, because it is entered JSONOBJCT then it must be pojo, otherwise it is the basic data type, it is impossible to enter the method
2. Iterate through all the properties of the instance and fetch values from Jsonobject
3. The corresponding class is obtained by the GetType method of reflection, which needs to distinguish between the basic type and the packing type.
4. If it is a list then go to the array method, if it is jsonobject then continue to recursively
5.JSONArray Direct parsing, if the string that is taken out contains classname, then it is Pojo continue recursion jsonobject, otherwise end, directly add into arraylist<object>
6. If it is a basic data type, call set assignment directly through reflection
7. If it is a list, then Jsonarray will return a list<object> direct set after recursion
Here, basically done, and then the near Lushu field can also be automatically encapsulated, anyway, save me a lot of time to get the value.
Click Get Sample Code
(original) JSON that writes Java tools is automatically encapsulated into Pojo