Skip to main content

Json parser library

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 + " ....");

List answer = (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

 

 

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.