JAVA: json string to Map<string, string> (or an object) - java

I'm looking for a simple json library to convert json-string to Map or a POJO object. I know it's a duplicate, still I got specific requirements:
no weird dependencies like json-lib (why do you need all of them for a simple task?)
use few lines of codes to accomplish it (KISS principle).
I prefer conversion to Map but POJO will be good almost as well.
that's it.
what do you suggest?

Jackson is good, but I think you can also give GSON a try.
It's simple and easy to use. And there is a unit test for converting json string to Map and vice versa.
Check this:MapTest.java
Hope this help you.

Jackson would be best in this case.

Related

Elegant mapping from POJOs to vertx.io's JsonObject?

I am currently working on a vertx.io application and wanted to use the provide mongo api for data storage. I currently have a rather clunky abstraction on top of the stock JsonObject classes where all get and set methods are replaced with things like:
this.backingObject.get(KEY_FOR_THIS_PROPERTY);
This is all well and good for now, but it won't scale particularly well. it also seems dirty, specifically when using nested arrays or objects. For example, if I want to be able to fill fields only when actual data is known, I have to check if the array exists, and if it doesn't create it and store it in the object. Then I can add an element to the list. For example:
if (this.backingObject.getJsonArray(KEY_LIST) == null) {
this.backingObject.put(KEY_LIST, new JsonArray());
}
this.backingObject.getJsonArray(KEY_LIST).add(p.getBackingObject());
I have thought about potential solutions but don't particularly like any of them. Namely, I could use Gson or some similar library with annotation support to handle loading the object for the purposes of manipulating the data in my code, and then using the serialize and unserialize function of both Gson and Vertx to convert between the formats (vertx to load data -> json string -> gson to parse json into pojos -> make changes -> serialize to json string -> parse with vertx and save) but that's a really gross and inefficient workflow. I could also probably come up with some sort of abstract wrapper that extends/implements the vertx json library but passes all the functionality through to gson, but that also seems like a lot of work.
Is there any good way to achieve more friendly and maintainable serialization using vertx?
I just submitted a patch to Vert.x that defines two new convenience functions for converting between JsonObject and Java object instances without the inefficiency of going through an intermediate JSON string representation. This will be in version 3.4.
// Create a JsonObject from the fields of a Java object.
// Faster than calling `new JsonObject(Json.encode(obj))`.
public static JsonObject mapFrom(Object obj)
// Instantiate a Java object from a JsonObject.
// Faster than calling `Json.decodeValue(Json.encode(jsonObject), type)`.
public <T> T mapTo(Class<T> type)
Internally this uses ObjectMapper#convertValue(...), see Tim Putnam's answer for caveats of this approach. The code is here.
I believe Jackson's ObjectMapper.convertValue(..) functions don't convert via String, and Vert.x is using Jackson for managing JsonObject anyway.
JsonObject just has an underlying map representing the values, accessible via JsonObject.getMap(), and a Jackson serializer/deserializer on the public ObjectMapper instance in io.vertx.core.json.Json.
To switch between JsonObject and a data model expressed in Pojos serializable with Jackson, you can do:
JsonObject myVertxMsg = ...
MyPojo pojo = Json.mapper.convertValue ( myVertxMsg.getMap(), MyPojo.class );
I would guess this is more efficient than going via a String (but its just a guess), and I hate the idea of altering the data class just to suit the environment, so it depends on the context - form vs performance.
To convert from Pojo to JsonObject, convert to a map with Jackson and then use the constructor on JsonObject:
JsonObject myobj = new JsonObject ( Json.mapper.convertValue ( pojo, Map.class ));
If you have implied nested JsonObjects or JsonArray objects in your definition, they will get instantiated as Maps and Lists by default. JsonObject will internally re-wrap these when you access fields specifying those types (e.g. with getJsonArray(..).
Because JsonObject is freeform and you're converting to a static type, you may get some unwanted UnrecognizedPropertyException to deal with. It may be useful to create your own ObjectMapper, add the vertx JsonObjectSerializer and JsonArraySerializer, and then make configuration changes to suit (such as DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES in Jackson).
Not sure if I've understood you correctly, but it sounds like you're trying to find a simple way of converting POJOs to JsonObject?
So, we have lots of pojos that we send over the EventBus as JsonObjects
I've found the easiest way is to use the vert.x Json class which has loads of helper methods to convert to / from Json Strings
JsonObject jsonObject = new JsonObject(Json.encode(myPojo));
Sometimes you need to add some custom (de)serializers, but we always stick with Jackson - that is what Vert.x is using so they work out of the box.
What we actually do, is provide an interface like the following:
public JsonObjectSerializable {
public JsonObject toJson();
}
And all our pojos that need to be sent over the EventBus have to implement this interface.
Then our EventBus sending code looks something like (simplified):
public <T extends JsonObjectSerializable> Response<T> dispatch(T eventPayload);
Also, as we generally don't unit test Pojos, adding this interface encourages the developers to unit test their conversion.
Hope this helps,
Will
Try this:
io.vertx.core.json.Json.mapper.convertValue(json.getMap(), cls)
I think that using Gson as you described is the best possible solution at the current time.
While I agree that if a protocol layer was included in Vert.x it would indeed be first prize, using Gson keeps your server internals pretty organised and is unlikely to be the performance bottleneck.
When and only when this strategy becomes the performance bottleneck have you reached the point to engineer a better solution. Anything before that is premature optimisation.
My two cents.
You can try:
new JsonObject().mapFrom(object)

Parse JSON String into raw Java types using Jackson?

I would like to parse some JSON string the represents either an array or a map in the simplest possible way. I have the whole JSON string, no streaming is needed.
What I would like to do is something as similar as possible to this:
Object obj = parseJSON(theString);
Where obj would then hold an instance of either a Map or a List (I cannot know in advance which). The JSON object can be arbitrarily nested with maps and arrays but all types will be representable as basic Java types: String, Integer, Double, Boolean plus Map and ArrayList, nothing else.
All the simple examples I have found so far require me to know what the type is and which types I want, but I want to let all this do the JSON parser since I simply will not know in advance what I get.
If Jackson is not the best library to do this, what else could I use?
All you need to do is this:
ObjectMapper mapper = new ObjectMapper();
Map<String,Object> map = mapper.readValue(theString, Map.class);
I'm pretty sure this returns a LinkedHashMap, if you care.
And in my opinion, you won't find a better serializer/deserializer for Java <-> JSON than Jackson. But there are many others like GSON.
Silly question, simple answer:
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
Object obj = mapper.readValue(theString, Object.class);
That seems to do exactly what I want. And it's so obvious too!
Another option should you decide to ditch Jackson (Jackson is fine, I'm quite agnostic in the JSON wars) is json-simple.
JSONObject jObject = JSONValue.parse(String jsonString);
Since JSONObject extends java.util.HashMap everything should work.

Parsing a json object which has many fields

I want to parse json from a server and place it into a class. I use json4s for this. The issue is that a json object contains too many fields, it's about 40-50 of them, some of them have the long names.
I wonder, what will be a sensible way to store all of them, will I have to create 40-50 fields in a class? Remember, some of them will have the long names, as I said earlier.
I use Scala, but a Java's approach might be similar to it, so I added a tag of Java also.
I don't know json4s but in Jersey with Jackson, for example, you can use a Map to hold the Json data or you can use a POJO with all those names.
Sometimes its better to have the names. It makes the code much easier to understand.
Sometimes its better to use a Map. For example, if the field names change from time to time.
If I recall it correctly, using pure Jackson you do something like this:
String jsonString = ....; // This is the string of JSON stuff
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory); // A Jackson class
Map<String,Object> data = mapper.readValue(jsonString, HashMap.class);
You can use a TypeReference to make it a little cleaner as regards the generics. Jackson docs tell more about it. There is also more here: StackOverflow: JSON to Map
There are generally two ways of parsing json to object
1) Parse json to object representation.
the other which might suit you as you mention that your object has too many fields is amap/hashtable, or you could just keep it as JObject, an get fields ehrn you need them

Mustache kind of String replacement in Java

My application allows users to define few templates for text etc. Eg: one of the shortcuts could be hi {{name}}, nice to meet you.
I have a complex json which has name and lot of inner jsons. I am looking for a good mustache kind of implementation in java which can replace the values of json into the string. Currently I am iterating through each key and replacing the string but I am looking for more elegant solution which gives the users more power in their templating like loops, conditions etc similar to mustache/handlebars.
Though mustache for java looks good, I haven't seen any implementation which can replace with a JSON. All examples applies on an object but not on a json object. Looks to me that internally, it uses an object mapper to convert an object to object and somehow it applies that.
Perhaps I can convert JSON into a map and provide it.
Probably I am missing something. Thanks.
You have to convert the JSON string to a Java object. You can use a nested Map, Multimap or create you own object to represent the structure.
You probably want to use a JSON-serializer to create a java object from the JSON-string. Good solutions are Jackson, Gson or Json-simple.
Once you have a correct Java representation of the JSON, you can use a template engine to do the string replacement. Known libraries are Freemarker, Velocity and StringTemplate
Personally I recommend Jackson+Freemarker, but all are good solutions.
Try Apache Velocity it does something very similar for property substitution in text.
Chunk is a very JSON-friendly template engine. Loops & conditions, tag syntax is similar to Mustache, and you can reference nested associative arrays of data fairly elegantly right from the template.
See sample code for JSON + Chunk in this answer.

Access nested json data in single get?

I am trying to trying to get a value out of a json object. How would I get a third level json object:
json format looks like:
feedString = {"level1":[{"level2":{"level3":{"valueIWant":10}}}]}
Code is:
JSONObject jsonFeed = new JSONObject(feedString);
jsonFeed.get("level1.level2.level3.valueIWant");
Can I get nested levels in one get? What should my key look like?
You could give JSONiJ (JSON in Java) a shot; it's a Java version of JSONPath and basically maps (a subset of) XPath syntax onto JSON objects.
Also, see this SO question for some other ideas; it looks like json-path has a Java version, and uses dot notation.
The other option is to build an EL bridge between JSONObjects and something like MVEL or OGNL, which would give you the more-familiar dot notation. (I thought there was an MVEL/JSON bridge, but can't find it now.)
You should use JSONPath. Check out this Java implementation http://code.google.com/p/json-path/
It's been a while now, but I have some good news. Just tried beanutils and it works like a charm!
Assuming you have the json converted to map: (any parser can do that)
private Map<String, Object> json;
All you need is:
PropertyUtils.getProperty(json, "level1.level2.level3.valueIWant")
Have fun :)

Categories

Resources