I am using Morphia (ver 0.99) for my JSON to Pojo mapping to my MongoDB (ver 2.0). Streaming data between web-clients and my server works fine. But now I have a use-case where I don't know what pattern that is most appropriate. Can I use Morphia or MongoDB Java driver to achieve my requirements or do I need to use Jackson and JPA 2.2 notation.
Here is my use-case;
Invoke Morphia query on selected collection (MongoDB)
The use the resulting ArrayList of Pojos for business logic and presentation (Primefaces)
Also convert the resulting ArrayList of Pojo's to JSON array of objects, but remove Pojo properties in the conversions that is not needed in the web-client
Push the converted JSON to the web-client for presentation
Converting one Pojo is straight forward with Morphia, but how do I convert an array?
return morph.toDBObject(obj).toString();
Is there a notation like #JsonIgnore in Morphia to ignore conversions to and from JSON ?
How can I most efficiently (without using more libraries if possible) to solve step three in in my use-case. Convert ArrayList to JSON and ignore conversion of some of the Pojo properties?
I've come up with a solution to my problem. It's maybe not the most elegant but it works the way I want and I don't have to include other libraries (like Gson and Jackson) to de-serialize my array list of Pojo's to Json, I only used classes from the MongoDB Java driver and the Morphia API. I also added a simple parameter list to strip away unnecessary property value to be pushed to the client.
public static String deserializeToJSON(List<?> objList, String... removeAttributes) {
List<DBObject> dbObjList = new ArrayList<>(objList.size());
DBObject dbObj;
for(Object obj :objList){
dbObj = morph.toDBObject(obj);
for(int i=0; i < removeAttributes.length; i++){
debug("Removed DBObject filed: " +dbObj.removeField(removeAttributes[i]));
}
dbObjList.add(dbObj);
}
String json = JSON.serialize(dbObjList);
return json;
}
Related
I've searched for a way to to convert a POJO into a BSON document. Unfortunately, the only answer you can find on the web is that MongoDB does this implicitly through the db.getCollection("some collection", Pojo.class) function. But there are some use cases where you want to convert a POJO into a BSON document.
One could be that you want to update a nested document in your MongoDB root document.
However, this isn't possible with the provided methods of the MongoDB Java Driver. The only way to do this is to write all the values manually in to a update expression.
db.getCollection("some collection", Pojo.class)
.updateOne(Filter.eq(id), Updates.set("myNestedDoc", new Document("some", "value"));
But it would be nice to do the same with a POJO. The advantages are obvious! Less duplicated code, better maintainable and less error prune.
But how can we accomplish this?
As described above, no answer can be found on the web. So I've searched the MongoDB Java Driver source code and found a way!
The BsonDocumentWrapper is a utility class to wrap a object as a BsonDocument. It uses the CodecRegistry which does the conversion internally.
db.getCollection("some collection", Pojo.class)
.updateOne(Filter.eq(id),
Updates.set("myNestedDoc",
BsonDocumentWrapper.asBsonDocument(lom, codecRegistry)));
)
You could also use the CodecRegistry object directly.
Pojo myPojo...
BsonDocument unwrapped = new BsonDocument();
BsonWriter writer = new BsonDocumentWriter(unwrapped);
Encoder<Pojo> encoder = codecRegistry.get(Pojo.class);
encoder.encode(writer, myPojo, EncoderContext.builder().build());
this.unwrapped = unwrapped;
But the utility class is more readable and maintainable.
This way you can safely use your existing POJOs to update your nested structures.
Keep in mind that you will replace the whole sub object, not only the fields that have been changed!
If you for some reason need to convert a BSON into a POJO you can use this sniped:
BsonDocument bson...
BsonReader reader = new BsonDocumentReader(bson);
Decoder<Pojo> encoder = codecRegistry.get(Pojo.class);
Pojo myPojo = encoder.decode(reader, DecoderContext.builder().build());
I hope this is useful to someone ;)
I have List<Person> where its JSON output is like:
[{"name":"john","email":"john#email.com"},
{"name":"daniel","email":"daniel#email.com"},
{"name":"thomas","email":"thomas#email.com"}]
and a count of the persons where its JSON format is like: {"number":3}
How can I combine the above two to get the result:
{
"number":3,
"persons":[{"name":"john","email":"john#email.com"},
{"name":"daniel","email":"daniel#email.com"},
{"name":"thomas","email":"thomas#email.com"}]
}
my Java code is jersey2 based JAX-RS application. to make more clear, I have a list of Person fetched from database and i also have an integer variable number. and combine the List and the integer variable to get above result in an efficient and robust way.
Since you are using a framework that already does conversion to JSON automatically, the easiest way would be to just return a new object.
public class Result {
private int number;
private List<Person> persons;
//leaving creation of constructor to you
}
And then just instantiate that object and return it.
When you want to map Object to json directly or want to convert json to object, you can use GSON library . this will give you more flexibility and control.
Download link - http://code.google.com/p/google-gson/
Tutorial link - http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/
I'm using vertx and Jackson in my development. In one of my classes, I got a field of type JsonObject, something like this:
class User
private String name;
private JsonObject details;
This details field can contain other JsonObjects or JsonArrays, e.g.:
{"details": [{"street": "Broadway"}, {"building": 20}]}
I don't have a dedicated class of this structure, as far as there's no fixed structure and it can vary.
details object is being created in the way like this:
JsonObject details = new JsonObject().put("name", "value").put("another", "another")
This aproach allows me to store details of any structure inside my code. As far as I don't need to manipulate this data on my backend, I don't want to create a special structure for it.
Everything works fine until I'm trying to serialize this JsonObject using Jackson. Unfortunately, instead of beatiful JSON string, Jackson gives me map object serialized with all map's additional fields.
How can I serialize JsonObject of vertx using Jackson?
Looking at JsonObject's javadoc , I saw a getMap() method. I know Jackson is capable of serializing Maps with ease.
Finally, it turned out that vertx already has it's own implementation of Serializer.
It's enough just to use theirs class to perform serialization (which will use Jackson undercover).
JsonObject user = new JsonObject(Json.encode(new User());
And it works fine.
I would suggest creating using https://static.javadoc.io/com.fasterxml.jackson.core/jackson-databind/2.7.3/com/fasterxml/jackson/databind/ObjectMapper.html#convertValue(java.lang.Object,%20java.lang.Class) like this:
new JsonObject((Map)Json.mapper.convertValue(new User(), Map.class));
Converting to and from String takes time.
I am developing a web application. I have database used by the web service. I want to send the same data to the web pages which are calling web service.
I get the data i.e. single row from the database by using hibernate and POJO classes(getColumn). Now I have object(POJO class) of the Table which represent single row of the database. For sending it back to the web pages (html, jsp), I need to convert it to the json object as my web service returns the json object.
How can I make Json object from POJO classes. There are many other ways to generate Json String but i want json object.
How can do this?
Thank you
You can use GSon to convert json object to java object
Link
to refer example.
Gson gson = new Gson();
//to get json object use toJson
String json = gson.toJson(obj);
//to get java object use fromJson
MyClass obj = gson.fromJson(jsonObj, MyClass.class);
or
jackson is also pretty fast and easy to use
private ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.convertValue(YOUR POJO CLASS, JsonNode.class);
You can use Jackson and achieve this as above. GSON also does the job.
The way I use is with Google's Gson library. Very simple and powerful
Spring and Jackson as it is so simple. You can find a very basic example below Jackson/spring JSON example
I' m developing a RESTful Android mobile client. Information exchange between my app and server is in JSON. So I' m now a little bit confused what data structure choose for represent JSON responses and data because there a lot of them. I've just stopped with LinkedHashMap<> but as far as i know JSON is unordered. Across the Internet I saw people use Map<> or HashMap<> for this. So the question - what is the best data structure for this purpose? Or if there is no a univocal answer - pros and cons of using data structures I' ve mentioned.
I would disagree with the first answer. The REST paradigm was developed so that you would operate with objects, rather than operations.
For me the most sensible approach will be if you declare beans on the client side and parse the json responses and request through them. I would recommend using the GSON library for the serialization/ deserialization. JsonObject/ JsonArray is almost never the best choice.
Maybe if you give examples of the operations you are about to use we might be able to help more precisely.
EDIT: Let me also give a few GSON Examples. Let's use this thread to compare the different libraries.
In the most cases REST services communicate objects. Let's assume you make a post of product, which has reference to shop.
{ "name": "Bread",
"price": 0.78,
"produced": "08-12-2012 14:34",
"shop": {
"name": "neighbourhood bakery"
}
}
Then if you declare the following beans:
public class Product {
private String name;
private double price;
private Date produced;
private Shop shop;
// Optional Getters and setters. GSON uses reflection, it doesn't need them
// However, better declare them so that you can access the fields
}
public class Shop {
private String name;
// Optional Getters and setters. GSON uses reflection, it doesn't need them
// However, better declare them so that you can access the fields
}
You can deserialize the json using:
String jsonString; // initialized as you can
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MM-dd-yyyy HH:mm"); // setting custom date format
Gson gson = gsonBuilder.create();
Product product = gson.fromJson(jsonString, Product.class);
// Do whatever you want with the object it has its fields loaded from the json
On the other hand you can serialize to json even more easily:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MM-dd-yyyy HH:mm"); // setting custom date format
Gson gson = gsonBuilder.create();
String jsonString = gson.toJson(product);
Are you talking about receiving and parsing the JSON string from a server request?
For that you can use:
import org.json.JSONArray;
import org.json.JSONObject;
Using these, I read through my JSON array from my POST request and store the resulting information in Class objects in my project.
For each item in JSONArray, you can extract the JSONObject and attributes like this:
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
jsonObject.getString("text");
}
As far as actually storing the data, like mentioned above, JSON data can come in a wide array of formats depending on the source, and as such, it is usually parsed on the client end and saved in your application Class objects for use. Or more generically, you could store the data using Map<String, Object>
This is easily the best answer I've seen:
https://dzone.com/articles/which-is-the-right-java-abstraction-for-json
Summary: there are three abstrations: pojos, maps and lists, and custom classes to represent objects, arrays, and primitives. There are advantages and disadvantages to each, with no clear winner.
Pojos have the biggest advantages, but you can't always use them. Use them if you can, and use the others if you must.
If you are doing anything other than the most simple mapping then you should use a full class structure. Create your class hierarchy as a mirror of the data structure in JSON and use Jackson to map the JSON directly to the class hierarchy using the ObjectMapper.
With this solution you don't have any casting of Object to Map or messing around with JSONObject or JSONArray and you don't have any multi-level map traversal in your code. You simply take the JSON string, feed it to the ObjectMapper, and get a your Object, which contains child objects (even collections) automatically mapped by the ObjectMapper.
I've used xstream to serialize JSON, in the following way:
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
xstream.setMode(XStream.NO_REFERENCES);
xstream.alias("myAlias", MyClass.class); // requires a no argument constructor
System.out.println(xstream.toXML(product));
Ok, the gentleman in the comments wants a deserialization example, here you are:
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
xstream.alias("myAlias", MyClass.class);
Product product = (Product)xstream.fromXML(json);
System.out.println(product.getName());
Let me know if you need further assistance...