Mapping between JSON formats in Java

I come in Java with JavaScript / Ruby. Let's say I have the following JSON object for an animal:

{ name: { common: "Tiger", latin: "Panthera tigris" } legs: 4 } 

I deal with a lot of animal APIs and I want to normalize them all to my own common format, for example:

 { common_name: "Tiger", latin_name: "Panthera tigris", limbs: { legs: 4, arms: 0 } } 

In, say, JavaScript, this would be simple:

 normalizeAnimal = function(original){ return { common_name: original.name.common, latin_name: original.name.latin, limbs: { legs: original.legs || 0, arms: original.arms || 0 } } } 

But what about Java? Using the JSONObject class from org.json, I could go this way:

 public JSONObject normalizeAnimal(JSONObject original) throws JSONException{ JSONObject name = original.getJSONObject("name"); JSONObject limbs = new JSONObject(); JSONObject normalized = new JSONObject(); normalized.put("name_name", name.get("common")); normalized.put("latin_name", name.get("latin")); try{ limbs.put("legs", original.get("legs"); }catch(e){ limbs.put("legs", 0); }; try{ limbs.put("arms", original.get("arms"); }catch(e){ limbs.put("arms", 0); }; normalized.put("limbs", limbs); return normalized; } 

This gets worse as the JSON objects I'm dealing with are getting longer and deeper. In addition to all this, I deal with many providers for animal objects, and ultimately I want to have a compressed configuration format for describing the transformations (for example, perhaps "common_name": "name.common", "limbs.legs": "legs" ).

How can I make it suck less in Java?

+6
source share
3 answers

Use a library like Gson or Jackson and map the JSON to the Java object.

So you will have a bean like

 public class JsonAnima { private JsonName name; private int legs; } public class JsonName { private String commonName; private String latinName; } 

which can be easily converted to any library with something like (with Jackson)

 ObjectMapper mapper = new ObjectMapper(); JsonAnimal animal = mapper.readValue(jsonString, JsonAnimal.class); 

then you can create a โ€œconverterโ€ to map JsonAnimal to the animal class.

This might be the way to do it. :)


Some links:

Gson: http://code.google.com/p/google-gson/

Jackson: http://wiki.fasterxml.com/JacksonHome

+5
source

If you will use this for many different types of objects, I would suggest using reflection instead of serializing each object manually. Using reflection, you don't need to create methods like normalizeAnimal, you just create one method or one class to serialize in json format.

If you are looking for "json java mapping" you will find useful links. Like gf. Here is an example that is on their website:

 class BagOfPrimitives { private int value1 = 1; private String value2 = "abc"; private transient int value3 = 3; BagOfPrimitives() { // no-args constructor } } //(Serialization) BagOfPrimitives obj = new BagOfPrimitives(); Gson gson = new Gson(); String json = gson.toJson(obj); ///==> json is {"value1":1,"value2":"abc"} ///Note that you can not serialize objects with circular references since that will result in infinite recursion. //(Deserialization) BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class); //==> obj2 is just like obj 
+1
source

In pure Java solutions, all problems are related to the unreliable structure of your source data. If you are working in the JVM, I recommend that you use Groovy to analyze and build your original JSON. The result is ultimately very similar to the Javascript solution described above:

 import groovy.json.JsonBuilder import groovy.json.JsonSlurper def originals = [ '{ "name": { "common": "Tiger", "latin": "Panthera tigris" }, "legs": 4 }', '{ "name": { "common": "Gecko", "latin": "Gek-onero" }, "legs": 4, "arms": 0 }', '{ "name": { "common": "Liger" }, "legs": 4, "wings": 2 }', '{ "name": { "common": "Human", "latin": "Homo Sapien" }, "legs": 2, "arms": 2 }' ] originals.each { orig -> def slurper = new JsonSlurper() def parsed = slurper.parseText( orig ) def builder = new JsonBuilder() // This builder looks a lot like the Javascript solution, no? builder { common_name parsed.name.common latin_name parsed.name.latin limbs { legs parsed.legs ?: 0 arms parsed.arms ?: 0 } } def normalized = builder.toString() println "$normalized" } 

Running the script above deals with jagged JSON (not all elements have the same attributes) and outputs like ...

 {"common_name":"Tiger","latin_name":"Panthera tigris","limbs":{"legs":4,"arms":0}} {"common_name":"Gecko","latin_name":"Gek-onero","limbs":{"legs":4,"arms":0}} {"common_name":"Liger","latin_name":null,"limbs":{"legs":4,"arms":0}} {"common_name":"Human","latin_name":"Homo Sapien","limbs":{"legs":2,"arms":2}} 
+1
source

Source: https://habr.com/ru/post/926542/


All Articles