Converter from Gson to MongoDB objects - java

Is anyone aware of a converter to transform from Gson to DBOjects for MongoDB, similarly to https://code.google.com/p/mongo2gson/ but in the other direction (i.e. gson2mongo)?
My aim is to convert a string (which is a valid JSONArray) into a DBObject, so that I can insert it into a Mongo database. There seems to be a standard technique for converting JSON objects into DBObject i.e
DBObject dbObject = (DBObject) JSON.parse("some json object string");
However, this approach does not work for JSONArrays and there doesn't seem to be a simple alternative. I've seen a few hacks that work for very simple JSONArrays, but nothing that could be used on a more complex structure. The gson library has some really useful stuff, and in the link above, this problem has been solved in one direction - (it allows you to convert from DBObjects to JsonArrays) but not the other way. Hopefully that's a little clearer!

I would suggest to use Jongo for interacting with MongoDB since Gson is only a JSON toolkit.
You can save, query and update POJOs with Jongo, that makes pretty much everything you need to with MongoDB.
Gson can be used to marshal JSON to POJOs and vice versa, but when it comes to interacting with MongoDB, you can use Jongo with confident.
They can be mixed too, like converting a REST response to a POJO with with the help of Gson then writing that information to MongoDB with Jongo.

Related

Double-formatting in com.fasterxml.jackson.databind.ObjectMapper

I have an application, which loads a data row from a SQL Server database and should transmit that content JSON-encoded to a webservice. I used ObjectMapper to do the JSON conversion. There is some infrastructure behind this project, namely I get the data from the db as a Hashmap<string,object> where the keys are the column-names from the db-table.
Is there a way to tell com.fasterxml.jackson.databind.ObjectMapper how to format double-values upon serialization, when you can not use annotations?
I did a simple
ObjectMapper o = new ObjectMapper();
String jsonStr = o.writeValueAsString(m); // m is my hashmap-instance
While in theory this works quite nicely, I have a problem with the serialization of doubles. In the db there is a column of type float (which corresponds to double in Java, java-float would be real in SQL Server) with the value 402.4818. If I let ObjectMapper serialize this, I get 402.48179999999996 in JSON.
How can I customize the double-formatting / precision in ObjectMapper? I have already used setDateFormat(new SimpleDateFormat("yyyy-MM-dd")) to get my dates right, is there any way to do something similar for double?
Most examples in the net serialize POJOs where you can use annotations to specify how specific properties should be serialized, but I have a HashMap here.
Please don't tell me that I have to go through the hassle of creating a POJO, fill it with the DB-Data and serialize it for every row I want to send via this API. (This is a db-row which has > 30 columns and the project is nearly done, besides this little double-formatting-problem.)
So what do I need to do to tell ObjectMapper to round to the 4. decimal point before serializing or give some custom DecimalFormat? Documentation on this is quite sparse.

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)

Parsing JSON into a string array or xml

I am trying to connect to a server which than connect to Google Places API and returns me my required data, the data that is being returned is in this format Here
Now in my Android Application i have this as a string or string[], issue is how can i now parse it as an XML or convert it to a native type like a List or something so i can than use it?
If you look at the returned string the actually array results starts after the two elemenets html_attributions & next_page_token so how can i seperate these and parse. Please help.
I would recommend you using the Gson library from Google, it can easily convert JSON -> Object . Here is a nice tutorial for you : tutorial.
This library is used by famous library Retrofit which is made for these calls and it will download the data and convert it to object using Gson : retrofit
There are a variety of ways to perform Json parsing in android.
If you only want to take the json and convert it to a java objects, then you can use gson. When serializing the object, gson will ignore any key in the json that doesn't match the java object that you are going to use for serialization. Therfore, just create your java object with the results instance variable,
https://code.google.com/p/google-gson/
You can use the built in JsonReader class to obtain the "results" and place that into a json array, if you want to single that out.
It is also good to become familiar with retrofit. This library provides a little more functionality than your solution needs however. This library abstracts the whole http request, response, json parsing and gson serializtion for you. So simply, you call a method on the object and get back the json in already serialized pojo.
http://square.github.io/retrofit/
If your returned data is in json format, create one JsonObject, Parse it as Json instead of xml, you can retrieve the value and create String[]. Take help from this tutorial
Of-course you can use Gson library to serialize and de-serialize jsonObject to pojoObject.
Ideally you should use a cool convenient library like Google GSON as mentioned by others for JSON parsing, but I'll explain how to use your json string with the old simple org.json library anyway. If your json string returned from server is in a string s, do:
JSONObject places=new JSONObject(s);
JSONArray results=places.getJSONArray("results");
for(int i=0;i<results.length();i++){
System.out.println(results.getJSONObject(i).getString("place_id"))
System.out.println(results.getJSONObject(i).getString("scope"));
}

Converter from Json into groovy CODE?

It's a kind of odd question for an odd situation. I have a large JSON structure which I would like to represent in running groovy code. I need groovy objects that mirror the same structure as the JSON objects.
As to be expected a web search mostly returns results with groovy/json runtime conversion stuff, but nothing about things that output groovy code.
You might think this lazy but really it is a massive JSON structure! A converter would save days!
You can use Groovy's own JsonSlurper to parse JSON objects:
import groovy.json.*
def json = '{"name":"john", "surname":"doe", "languages": ["groovy", "python"]}'
def obj = new JsonSlurper().parseText(json)
assert obj.name == "john"
assert obj.surname == "doe"
assert obj.languages.containsAll("python", "groovy")
Of course the class is untyped: it's only known at runtime. If you want it to be typed, you can write a code which writes the code based on an example (since a json schema may be rare).
EDIT: if you want to generate the model classes code, you can try JSONGen, which "parses JSON to create client side source files to model the JSON data structure". I'm not aware of a solution for Groovy, but since java-groovy integrations is seamless, it shall work fine.
If you want a Groovy representation of your JSON, you can get that via the built-in JsonSlurper. This will give you Java Maps and Lists of data you can work with.
You can populate more specific, custom objects you've written to represent your JSON entities using the (3rd party) Jackson's data binding functionality (see this question as well).
Try using a JSON parser like this one. According to its documentation you just need to do
JSON.parse
to deserialize the data

What is the the best way to convert JSONObject to a domain object?

I have a rest service returning some data. I use Restlet client api as shown below to access this service. As you can see, it returns org.json.JSONObject. Is there a easy way to map this to the domain object (may be through annotations?) or should I have to write code to create the domain object?
Representation entity = new ClientResource(uri).get();
JSONObject json = new JsonRepresentation(entity).getJsonObject();
May be you can leverage from Gson library which has a function you need:
// Convert JSON into Java object
SomeObj obj = gson.fromJson(jsonObjStr, SomeObj.class)
You can read more here...
While there are decent APIs for easily mapping between Java data structures, e.g., from the JSONObject to your preferred data structure, since the incoming data format is JSON, I'd much prefer to just use a good JSON-to/from-Java API like Jackson. Depending on the preferred transformation details, the solution might be just one simple line of code with such an API.

Categories

Resources