VostokJsonLib is a library for convertion between java object/bean and json object. Perhaps not the faster one but thanks for the use of reflection, it's definitively one of the easy one; Conversion is typically done with a single method call. In most situation custom parser isn't even needed !
- Simple, create an instance, call a method, that's all !
- Based on reflection, it can parse complex class/bean out of the box (*)
- No configuration needed (*)
- Need complex data structure ? no problem, just define a converter from a simple interface
- Some fields to discard or keep private, just put an annotation on them
- Enforce strict or lazy conversion, you choose
- Lightweight, only one 35Kb jar
- No dependencies needed, link it to your project and just use it
(*) If made of primitive type, on special data structure you may need to define additional converters.
Code example
This is just few test case, don't forget to download the additional runnable sample code for a full detail and test it yourself.
Some primitive, Json to java
// We using the default instance Unmarshaller bp = JSONContext.getInstance().getUnmarshaller(); System.out.println("\n\n---------------- parsing some primitive based ------------------"); System.out.println("#parsing a string : \"my json string\"...."); String str = (String) bp.unmarshal(String.class, "my json string"); System.out.println("answer : " + str + " (" + str.getClass().getCanonicalName() + ")\n"); System.out.println("#parsing an integer :\"666\"...."); Integer val = (Integer) bp.unmarshal(Integer.class, "666"); System.out.println("answer : " + val + " (" + val.getClass().getCanonicalName() + ")\n"); System.out.println("#parsing a simple int array : \"[1,2,3,4]\"...."); int[] vali = (int[]) bp.unmarshal(int[].class, "[1,2,3,4]"); System.out.println("answer : " + vali[0] + " " + vali[1] + " " + vali[2] + " " + vali[3] + " (" + vali.getClass().getCanonicalName() + ")\n");
---------------- parsing some primitive based ------------------ #parsing a string : "my json string".... answer : my json string (java.lang.String) #parsing an integer :"666".... answer : 666 (java.lang.Integer) #parsing a simple int array : "[1,2,3,4]".... answer : 1 2 3 4 (int[])
Some primitive, java to json
Marshaller bp = JSONContext.getInstance().getMarshaller(); System.out.println("\n\n---------------- building some primitive based ------------------"); String str = "My string xyz"; System.out.println("#building a string : " + str + "...."); System.out.println("answer : " + bp.marshal(str) + " (" + str.getClass().getCanonicalName() + ")\n"); Double d = Math.PI; System.out.println("#building a double : " + d + "...."); System.out.println("answer : " + bp.marshal(d) + " (" + d.getClass().getCanonicalName() + ")\n"); Integer[] vala = new Integer[]{10, 20, 30, 40}; System.out.println("#parsing an Integer array : \"" + vala + "\"...."); System.out.println("answer : " + bp.marshal(vala) + " (" + vala.getClass().getCanonicalName() + ")\n");
---------------- building some primitive based ------------------ #building a string : My string xyz.... answer : "My string xyz" (java.lang.String) #building a double : 3.141592653589793.... answer : 3.141592653589793 (java.lang.Double) #parsing an Integer array : "[Ljava.lang.Integer;@47415dbf".... answer : [ 10,20,30,40] (java.lang.Integer[])
Working with object and generic, Json to java
Unmarshaller bp = JSONContext.getInstance().getUnmarshaller(); String data = "[\"first\",\"second\",\"third\"]"; System.out.println("\n\n---------------- parsing List with generic ------------------"); System.out.println("#source : " + data + " ...."); Listanswer = (List ) bp.unmarshal(List.class, String.class, data); System.out.println("Start loop, list is " + answer.size() + " element(s) (" + answer.getClass().getCanonicalName() + ")"); for (String s : answer) { System.out.println("answer from List : " + s); }
---------------- parsing List with generic ------------------ #source : ["first","second","third"] .... Start loop, list is 3 element(s) (java.util.ArrayList) answer from List : first answer from List : second answer from List : third
Array of bean, Json to java
With bean (or pojo) setter are mandatory. Note the variable "thatval", it was just ignored.
Unmarshaller bp = JSONContext.getInstance().getUnmarshaller(); String data = "[{val:\"first\", thatval:\"don't exit\"},{val:\"second\"},{val:\"third\"}]"; System.out.println("\n\n---------------- parsing a simple array of bean ------------------"); System.out.println("#source : " + data + " ...."); SimpleBean[] array = (SimpleBean[]) bp.unmarshal(SimpleBean[].class, data); System.out.println("Start loop, array is " + array.length + " element(s) (" + array.getClass().getCanonicalName() + ")"); for (SimpleBean b : array) { System.out.println("answer from bean : " + b.getVal()); }
---------------- parsing a simple array of bean ------------------ #source : [{val:"first", thatval:"don't exit"},{val:"second"},{val:"third"}] .... Start loop, array is 3 element(s) (vostokjsonlibsample.bean.SimpleBean[]) answer from bean : first answer from bean : second answer from bean : third
public class SimpleBean { String val; String val2; String dummy; public String getVal() { return val; } public void setVal(String val) { this.val = val; } public String getVal2() { return val2; } public void setVal2(String val2) { this.val2 = val2; } @Discard public String getDummy() { return dummy; } public void setDummy(String dummy) { this.dummy = dummy; } }
Array of bean, java to json
This also demonstrate the use of @discard
Marshaller bp = JSONContext.getInstance().getMarshaller(); SimpleBean bean = new SimpleBean(); bean.setVal("my value"); System.out.println("\n\n---------------- building a Simple bean ------------------"); System.out.println("#source : " + bean.toString() + "(" + bean.getClass().getCanonicalName() + ") ...."); System.out.println("#nota : @discard annotation on dummy field"); System.out.println("#answer : " + bp.marshal(bean));
---------------- building a Simple bean ------------------ #source : SimpleBean{val=my value, val2=null, dummy=null}(vostokjsonlibsample.bean.SimpleBean) .... #nota : @discard annotation on dummy field #answer : { "val2":null,"val":"my value"}
Using a converter
sometime you will need to provide your own converter, for example when filed format doesn't match.
This example demonstrate the use of both regular and converter on a fictional LatLng class. Default instance will translate into a js list, with converter as an array.
Note a context cannot handle several formatting for the same java class. As demonstrated by this example, you will have to work with different context.
public class LatLng { double lat; double lng; public double getLat() { return lat; } public void setLat(double lat) { this.lat = lat; } public double getLng() { return lng; } public void setLng(double lng) { this.lng = lng; } @Override public String toString() { return "LatLng{" + "lat=" + lat + ", lng=" + lng + '}'; } }
public class LatLngConverter implements ObjectConverterInterface { static Pattern p = Pattern.compile("\\s*\\[\\s*([\\d\\.]+)\\s*,\\s*([\\d\\.]+)\\s*\\]\\s*"); @Override public String getString(Object obj) throws ParserException { if (obj instanceof LatLng == false) { throw new ParserException("Not a LatLng obj"); } LatLng ll = (LatLng) obj; StringBuilder str = new StringBuilder("[").append(ll.getLat()).append(',').append(ll.getLng()).append(']'); return str.toString(); } @Override public Object getObject(String data) throws ParserException { try { Matcher m = p.matcher(data); if (m.matches()) { LatLng o = new LatLng(); o.setLat(Double.valueOf(m.group(1))); o.setLng(Double.valueOf(m.group(2))); return o; } } catch (Exception e) { e.printStackTrace(); } throw new ParserException("can't parse data into a LatLng object"); } }
Marshaller bp = JSONContext.getInstance().getMarshaller(); JSONContext context = new JSONContext(true, LatLng.class.getCanonicalName(), LatLngConverter.class); System.out.println("\n\n---------------- building a LatLng object ------------------"); System.out.println("Demonstrate how to translate a LatLng object not into a js list but an array using converter\n"); LatLng ll = new LatLng(); ll.setLat(55.754397); ll.setLng(37.619997); System.out.println("#source : " + ll + "(" + ll.getClass().getCanonicalName() + ") ...."); System.out.println("#answer with default builder : " + bp.marshal(ll)); System.out.println("#answer with extended builder : " + context.getMarshaller().marshal(ll));
---------------- building a LatLng object ------------------ Demonstrate how to translate a LatLng object not into a js object but an array using converter #source : LatLng{lat=55.754397, lng=37.619997}(vostokjsonlibsample.bean.LatLng) .... #answer with default builder : { "lat":55.754397,"lng":37.619997} #answer with extended builder : [55.754397,37.619997]
for more complex test case, please open the sample project
Install
VostokJsonLib is made of a single jar with no dependencies. Just download the jar - 35Ko - and link it to your project
Download
- Download the jar : VostokJsonLib-1.4.jar
- Download the javadocs : VostokJsonLib-javadoc-1.4.tar.gz
- Download the sample source code (netbeans project) : VostokJsonLibSample.tar.gz
Maven repository
A repository will be available soon
Javadocs
Licence
VostokJsonLib is provided for free, for community, private or commercial work under the creative commons licence, CC-BY, no attribution needed.