Is there a simple way to convert Simple POJO to org.bson.Document?
I'm aware that there are ways to do this like this one:
Document doc = new Document();
doc.append("name", person.getName()):
But does it have a much simpler and typo less way?
Currently Mongo Java Driver 3.9.1 provide POJO support out of the box
http://mongodb.github.io/mongo-java-driver/3.9/driver/getting-started/quick-start-pojo/
Let's say you have such example collection with one nested object
db.createCollection("product", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "description", "thumb"],
properties: {
name: {
bsonType: "string",
description: "product - name - string"
},
description: {
bsonType: "string",
description: "product - description - string"
},
thumb: {
bsonType: "object",
required: ["width", "height", "url"],
properties: {
width: {
bsonType: "int",
description: "product - thumb - width"
},
height: {
bsonType: "int",
description: "product - thumb - height"
},
url: {
bsonType: "string",
description: "product - thumb - url"
}
}
}
}
}
}});
1. Provide a MongoDatabase bean with proper CodecRegistry
#Bean
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString("mongodb://username:password#127.0.0.1:27017/dbname");
ConnectionPoolSettings connectionPoolSettings = ConnectionPoolSettings.builder()
.minSize(2)
.maxSize(20)
.maxWaitQueueSize(100)
.maxConnectionIdleTime(60, TimeUnit.SECONDS)
.maxConnectionLifeTime(300, TimeUnit.SECONDS)
.build();
SocketSettings socketSettings = SocketSettings.builder()
.connectTimeout(5, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.build();
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.applyToConnectionPoolSettings(builder -> builder.applySettings(connectionPoolSettings))
.applyToSocketSettings(builder -> builder.applySettings(socketSettings))
.build();
return MongoClients.create(clientSettings);
}
#Bean
public MongoDatabase mongoDatabase(MongoClient mongoClient) {
CodecRegistry defaultCodecRegistry = MongoClientSettings.getDefaultCodecRegistry();
CodecRegistry fromProvider = CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build());
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(defaultCodecRegistry, fromProvider);
return mongoClient.getDatabase("dbname").withCodecRegistry(pojoCodecRegistry);
}
2. Annotate your POJOS
public class ProductEntity {
#BsonProperty("name") public final String name;
#BsonProperty("description") public final String description;
#BsonProperty("thumb") public final ThumbEntity thumbEntity;
#BsonCreator
public ProductEntity(
#BsonProperty("name") String name,
#BsonProperty("description") String description,
#BsonProperty("thumb") ThumbEntity thumbEntity) {
this.name = name;
this.description = description;
this.thumbEntity = thumbEntity;
}
}
public class ThumbEntity {
#BsonProperty("width") public final Integer width;
#BsonProperty("height") public final Integer height;
#BsonProperty("url") public final String url;
#BsonCreator
public ThumbEntity(
#BsonProperty("width") Integer width,
#BsonProperty("height") Integer height,
#BsonProperty("url") String url) {
this.width = width;
this.height = height;
this.url = url;
}
}
3. Query mongoDB and obtain POJOS
MongoCollection<Document> collection = mongoDatabase.getCollection("product");
Document query = new Document();
List<ProductEntity> products = collection.find(query, ProductEntity.class).into(new ArrayList<>());
And that's it !!! You can easily obtain your POJOS
without cumbersome manual mappings
and without loosing ability to run native mongo queries
You can use Gson and Document.parse(String json) to convert a POJO to a Document. This works with the version 3.4.2 of java driver.
Something like this:
package com.jacobcs;
import org.bson.Document;
import com.google.gson.Gson;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
public class MongoLabs {
public static void main(String[] args) {
// create client and connect to db
MongoClient mongoClient = new MongoClient("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("my_db_name");
// populate pojo
MyPOJO myPOJO = new MyPOJO();
myPOJO.setName("MyName");
myPOJO.setAge("26");
// convert pojo to json using Gson and parse using Document.parse()
Gson gson = new Gson();
MongoCollection<Document> collection = database.getCollection("my_collection_name");
Document document = Document.parse(gson.toJson(myPOJO));
collection.insertOne(document);
}
}
I don't know your MongoDB version. But now-a-days, there is no need to convert Document to POJO or vice versa. You just need to create your collection depending on what you want to work with, Document or POJO as follows.
//If you want to use Document
MongoCollection<Document> myCollection = db.getCollection("mongoCollection");
Document doc=new Document();
doc.put("name","ABC");
myCollection.insertOne(doc);
//If you want to use POJO
MongoCollection<Pojo> myCollection = db.getCollection("mongoCollection",Pojo.class);
Pojo obj= new Pojo();
obj.setName("ABC");
myCollection.insertOne(obj);
Please ensure your Mongo DB is configured with proper codecregistry if you want to use POJO.
MongoClient mongoClient = new MongoClient();
//This registry is required for your Mongo document to POJO conversion
CodecRegistry codecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().automatic(true).build()));
MongoDatabase db = mongoClient.getDatabase("mydb").withCodecRegistry(codecRegistry);
The point is, that you do not need to put your hands on org.bson.Document.
Morphia will do all that for you behind the curtain.
import com.mongodb.MongoClient;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.DatastoreImpl;
import org.mongodb.morphia.Morphia;
import java.net.UnknownHostException;
.....
private Datastore createDataStore() throws UnknownHostException {
MongoClient client = new MongoClient("localhost", 27017);
// create morphia and map classes
Morphia morphia = new Morphia();
morphia.map(FooBar.class);
return new DatastoreImpl(morphia, client, "testmongo");
}
......
//with the Datastore from above you can save any mapped class to mongo
Datastore datastore;
final FooBar fb = new FooBar("hello", "world");
datastore.save(fb);
Here you will find several examples: https://mongodb.github.io/morphia/
If you are using Morphia, you can convert a POJO to document using this piece of code.
Document document = Document.parse( morphia.toDBObject( Entity ).toString() )
If you are not using Morphia, then you can do the same by writing custom mapping and converting the POJO into a DBObject and further converting the DBObject to a string and then parsing it.
If you use Spring Data MongoDB with springboot, MongoTemplate has a method to do this well.
Spring Data MongoDB API
Here's a sample.
1.First autowire the mongoTemplate in spring boot project.
#Autowired
MongoTemplate mongoTemplate;
2.Use mongoTemplate in your service
Document doc = new Document();
mongoTemplate.getConverter().write(person, doc);
In order to do this, you need config your pom file and yml to inject mongotemplate
pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.1.10.RELEASE</version>
</dependency>
application.yml
# mongodb config
spring:
data:
mongodb:
uri: mongodb://your-mongodb-url
No i think it can be usefull for bulkInsert. I think bulkInsert cannot work with pojo (if i'm not mistaken).
If someone know how to user bulkInsert
Related
I have a spring-boot project, with spring-data-mongo dependency. Everything is working great. I have a service which basically does a listCollections on one of the DB and clears the content of all the collections in that DB.
Code:
public void clearContentsOfAllCollections() {
MongoDatabase db = this.mongoTemplate.getMongoDbFactory().getDb("any-db-name");
LOGGER.info("=================================================================");
LOGGER.info("Clearing collections in DB - {}", db.getName());
MongoIterable<String> collectionNames = db.listCollectionNames();
for (final String collectionName : collectionNames) {
LOGGER.info("Clearing collection - {}", collectionName);
db.getCollection(collectionName).deleteMany(new Document());
}
LOGGER.info("Successfully cleared DB - {}", db.getName());
LOGGER.info("=================================================================");
}
When I try to write unit test, this is what I have
#Test
public void dropDBTest() {
SimpleMongoClientDbFactory simpleMongoClientDbFactory = Mockito.mock(SimpleMongoClientDbFactory.class);
MongoDatabase mongoDatabase = Mockito.mock(MongoDatabase.class);
Mockito.when(mongoTemplate.getMongoDbFactory()).thenReturn(simpleMongoClientDbFactory);
Mockito.when(simpleMongoClientDbFactory.getDb("db-name"))
.thenReturn(mongoDatabase);
// How do I convert this array list into a Mongo iterable
List<String> collectionList = Arrays.asList("collection-1", "collection-2");
}
The problem is - I do not know how I can return the content of collectionList, when I have to mock database.listCollectionNames() (from package com.mongodb.client).
Morever, the iterable.iterator() is of type MongoCursor. How do I test this? Am I missing something?
public class MongoDBTest {
#Test
public void testListCollectionNames() {
// Set up the mock MongoDatabase
MongoDatabase mockDatabase = Mockito.mock(MongoDatabase.class);
// Set up the mock MongoIterable<String>
MongoIterable<String> mockIterable = Mockito.mock(MongoIterable.class);
Mockito.when(mockDatabase.listCollectionNames()).thenReturn(mockIterable);
final var collectionNames = new ArrayList<>();
collectionNames.add("testCollection")
doReturn(collectionNames).when(mockIterable).into(new ArrayList<>());
// Get the list of collection names
List<String> collectionNames = mockDatabase.listCollectionNames().into(new ArrayList<>());
// Assert that the test collection is in the list
assertEquals(true, collectionNames.contains("testCollection"));
}
}
I have a Java Class named Status and it consists of 3 fields namely : String Email, String Status, ArrayList(Comment) commentList. Comment is another Java class consisting of 2 String field. I have worked with MySQL and i know how i could save this Status object in database table. Now i am learning MongoDB and i need this Status object to store in my db collection. How do i do it? As of now i have tried the following and failed to store the Status object. Can anyone please help me with it?
I have tried the following :
public static MongoClient getMongoConnection() {
MongoClient mongo = null;
try {
mongo = new MongoClient("localhost", 27017);
} catch (Exception e) {
e.printStackTrace();
}
return mongo;
}
public static void main(String[] args) {
MongoClient mongo = getMongoConnection();
DB db = mongo.getDB("myTestdatabase");
DBCollection myReviews = db.getCollection("myStatus");
BasicDBObject obj = new BasicDBObject();
List<Object> commentList = new BasicDBList();
commentList.add(new Comment("Looks like a nice status", "email#gmail.com"));
commentList.add(new Comment("This is a nice status", "email#gmail.com"));
Status status = new Status();
status.setStatus("This is my new Status");
status.setEmail("email#gmail.com");
obj.put("status", status.getStatus());
obj.put("email", status.getEmail());
obj.put("comments", commentList);
myReviews.insert(obj);
}
I get this error.
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.Comment.
mongo.getDB is depreciated. Use the below to create your DB. Make sure you import bson as well.
MongoClient mongo = new MongoClient("localhost", 27017);
MongoDatabase db = mongo.getDatabase("myDB");
MongoCollection items = db.getCollection("myCollection");
Document document = new Document(); // Create the document to be inserted to the DB
document.put("First Name", "John");
document.put("Last Name", "Smith");
items.insertOne(document); // Insert document to DB
I am struggling with importing data into Mongodb from a Json file.
I can do the same in command line by using mongoimport command.
I explored and tried lot but not able to import from Json file using java.
sample.json
{ "test_id" : 1245362, "name" : "ganesh", "age" : "28", "Job" :
{"company name" : "company1", "designation" : "SSE" }
}
{ "test_id" : 254152, "name" : "Alex", "age" : "26", "Job" :
{"company name" : "company2", "designation" : "ML" }
}
Thank for your time.
~Ganesh~
Suppose you can read the JSON string respectively. For example, you read the first JSON text
{ "test_id" : 1245362, "name" : "ganesh", "age" : "28", "Job" :
{"company name" : "company1", "designation" : "SSE" }
}
and assign it to a variable (String json1), the next step is to parse it,
DBObject dbo = (DBObject) com.mongodb.util.JSON.parse(json1);
put all dbo into a list,
List<DBObject> list = new ArrayList<>();
list.add(dbo);
then save them into database:
new MongoClient().getDB("test").getCollection("collection").insert(list);
EDIT:
In the newest MongoDB Version you have to use Documents instead of DBObject, and the methods for adding the object look different now. Here's an updated example:
Imports are:
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
The code would like this (refering to the text above the EDIT):
Document doc = Document.parse(json1);
new MongoClient().getDataBase("db").getCollection("collection").insertOne(doc);
you can also do it the way with the list. but then you need
new MongoClient().getDataBase("db").getCollection("collection").insertMany(list);
But I think there is a problem with this solution. When you type:
db.collection.find()
in the mongo shell to get all objects in the collection, the result looks like the following:
{ "_id" : ObjectId("56a0d2ddbc7c512984be5d97"),
"test_id" : 1245362, "name" : "ganesh", "age" : "28", "Job" :
{ "company name" : "company1", "designation" : "SSE"
}
}
which is not exactly the same as before.
Had a similar "problem" myself and ended up using Jackson with POJO databinding, and Morphia.
While this sound a bit like cracking a nut with a sledgehammer, it is actually very easy to use, robust and quite performant and easy to maintain code wise.
Small caveat: You need to map your test_id field to MongoDB's _id if you want to reuse it.
Step 1: Create an annotated bean
You need to hint Jackson how to map the data from a JSON file to a POJO. I shortened the class a bit for the sake of readability:
#JsonRootName(value="person")
#Entity
public class Person {
#JsonProperty(value="test_id")
#Id
Integer id;
String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
As for the embedded document Job, please have a look at the POJO data binding examples linked.
Step 2: Map the POJO and create a datastore
Somewhere during your application initialization, you need to map the annotated POJO. Since you already should have a MongoClient, I am going to reuse that ;)
Morphia morphia = new Morphia();
morphia.map(Person.class);
/* You can reuse this datastore */
Datastore datastore = morphia.createDatastore(mongoClient, "myDatabase");
/*
* Jackson's ObjectMapper, which is reusable, too,
* does all the magic.
*/
ObjectMapper mapper = new ObjectMapper();
Do the actual importing
Now importing a given JSON file becomes as easy as
public Boolean importJson(Datastore ds, ObjectMapper mapper, String filename) {
try {
JsonParser parser = new JsonFactory().createParser(new FileReader(filename));
Iterator<Person> it = mapper.readValues(parser, Person.class);
while(it.hasNext()) {
ds.save(it.next());
}
return Boolean.TRUE;
} catch (JsonParseException e) {
/* Json was invalid, deal with it here */
} catch (JsonMappingException e) {
/* Jackson was not able to map
* the JSON values to the bean properties,
* possibly because of
* insufficient mapping information.
*/
} catch (IOException e) {
/* Most likely, the file was not readable
* Should be rather thrown, but was
* cought for the sake of showing what can happen
*/
}
return Boolean.FALSE;
}
With a bit of refatcoring, this can be converted in a generic importer for Jackson annotated beans.
Obviously, I left out some special cases, but this would out of the scope of this answer.
With 3.2 driver, if you have a mongo collection and a collection of json documents e.g:
MongoCollection<Document> collection = ...
List<String> jsons = ...
You can insert individually:
jsons.stream().map(Document::parse).forEach(collection::insertOne);
or bulk:
collection.insertMany(
jsons.stream().map(Document::parse).collect(Collectors.toList())
);
I just faced this issue today and solved it in another different way while none here satisfied me, so enjoy my extra contribution. Performances are sufficient to export 30k documents and import them in my Springboot app for integration test cases (takes a few seconds).
First, the way your export your data in the first place matters.
I wanted a file where each line contains 1 document that I can parse in my java app.
mongo db --eval 'db.data.find({}).limit(30000).forEach(function(f){print(tojson(f, "", true))})' --quiet > dataset.json
Then I get the file from my resources folder, parse it, extract lines, and process them with mongoTemplate. Could use a buffer.
#Autowired
private MongoTemplate mongoTemplate;
public void createDataSet(){
mongoTemplate.dropCollection("data");
try {
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(DATASET_JSON);
List<Document> documents = new ArrayList<>();
String line;
InputStreamReader isr = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
documents.add(Document.parse(line));
}
mongoTemplate.insert(documents,"data");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
List<Document> jsonList = new ArrayList<Document>();
net.sf.json.JSONArray array = net.sf.json.JSONArray.fromObject(json);
for (Object object : array) {
net.sf.json.JSONObject jsonStr = (net.sf.json.JSONObject)JSONSerializer.toJSON(object);
Document jsnObject = Document.parse(jsonStr.toString());
jsonList.add(jsnObject);
}
collection.insertMany(jsonList);
Runtime r = Runtime.getRuntime();
Process p = null;
//dir is the path to where your mongoimport is.
File dir=new File("C:/Program Files/MongoDB/Server/3.2/bin");
//this line will open your shell in giving dir, the command for import is exactly same as you use mongoimport in command promote
p = r.exec("c:/windows/system32/cmd.exe /c mongoimport --db mydb --collection student --type csv --file student.csv --headerline" ,null,dir);
public static void importCSV(String path) {
try {
List<Document> list = new ArrayList<>();
MongoDatabase db = DbConnection.getDbConnection();
db.createCollection("newCollection");
MongoCollection<Document> collection = db.getCollection("newCollection");
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while ((line = reader.readLine()) != null) {
String[] item = line.split(","); // csv file is "" separated
String id = item[0]; // get the value in the csv assign keywords
String first_name = item[1];
String last_name = item[2];
String address = item[3];
String gender = item[4];
String dob = item[5];
Document document = new Document(); // create a document
document.put("id", id); // data into the database
document.put("first_name", first_name);
document.put("last_name", last_name);
document.put("address", address);
document.put("gender", gender);
document.put("dob", dob);
list.add(document);
}
collection.insertMany(list);
}catch (Exception e){
System.out.println(e);
}
}
I have a web service that returns JSON strings one by one based on query inputs, a GET request to the service returns this (there's only one entry in the database)
[{"checked":false,"dateposted":"2014-10-23T00:00:00","itemnumber":1,"quantity":5,"stockcheckid":1}]
at the moment I just have this System.out.println in a while loop.
what I want to do is be able to access these results in a way that I can input them into a jtable to display on a client application. I've read some guides about reading from JSON files etc but I cant find anything specific to REST web services. I hear GSON mentioned a lot, i tried that but i cant quite work out how to make it work in this context
I should also mention that the service can also send this data in XML format.
Do I somehow create a JSON file appending each new entry to it? and then populate the table from that file?
anyway here's the code that initiates the GET request.
public static void getRequest(String dataGet) {
try {
URL url = new URL("http://localhost:8080/nXXXXXXXXc/webresources/entities.stockchecks/" + dataGet);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}`
The response is a map. You can serialise a JSON map to a Java map with Jackson like this:
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONtoMap {
public static final String json = "{\"B\":\"b\",\"C\":\"c\"}";
public static class POJO{
private Map<String,String> map = new TreeMap<String,String>();
#JsonAnyGetter
public Map<String, String> get() {
return map;
}
#JsonAnySetter
public void set(String name, String value) {
map.put(name, value);
}
}
#Test
public final void test() throws JsonProcessingException, IOException {
ObjectMapper jsonmapper = new ObjectMapper();
POJO p = jsonmapper.readValue(json, POJO.class);
assertEquals(jsonmapper.writeValueAsString(p),json);
}
}
I imagine you could do something similar with GSON. Another option is if you know the structure of the JSON object - in that case you make a simple POJO version and de-serialise into that instead of something like the POJO class I've defined above.
More detail and a similar version that supports XML as well as JSON mapping
Irrespective of how you obtain the data, use it to construct a suitable TableModel and use that model to construct the JTable. In this example, the model accesses a Map<String, String> to fulfill the TableModel contract; you can substitute the Map obtained using the approach shown here. Because loading the data may take an indeterminate amount of time, use a SwingWorker, as shown here.
This is simply a combination of trashgod's and tom's answer, with an example, using Jackson and a TableModel. I really just want to give camickr's BeanTableModel/RowTableModel (which is a generic class to help us easily create table models to from pojos) a try (seems to work great).
For more information/details please see this post
Entity class (properties mapped to the keys in your json)
public class Entity {
// field/property names must match to your json keys (with some exceptions)
// other wise we are required to use further annotations
private boolean checked;
private Date dateposted;
private int itemnumber;
private int quantity;
private int stockcheckid;
/*** ----- DO NOT FORGET GETTERS AND SETTERS ---- ***/
}
Main class. Note the use BeanTableModel. You will need to download this class along with RowTableModel from the link above.
public class JsonTableDemo {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = "[{\"checked\":false,\"dateposted\":\"2014-10-23T00:00:00\",\"itemnumber\":1,\"quantity\":5,\"stockcheckid\":1}]";
List<Entity> response = mapper.readValue(json,
TypeFactory.defaultInstance().constructCollectionType(
List.class, Entity.class));
RowTableModel model = new BeanTableModel<>(Entity.class, response);
JTable table = new JTable(model) {
#Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
};
JOptionPane.showMessageDialog(null, new JScrollPane(table));
}
}
Result
Note, for long running task (many io task included), such as requesting a rest resource, you should use a SwingWorker as explained by trashgod. When the repsonse comes in, you can basically addRow to the RowTableModel instance. For instance if we use the same json response and model as above, we could simply do something like
response = mapper.readValue(json,
TypeFactory.defaultInstance().constructCollectionType(
List.class, Entity.class));
for (Entity entity : response) {
model.addRow(entity);
}
UPDATE
I should also mention that the service can also send this data in XML format.
Looking at your json, it is an array of objects. With XML, the format is a little different, as you must have a root document element. So you can't just have say
<entity>
<prop></prop>
</entity>
<entity>
<prop></prop>
</entity>
It would need to be something like
<entities>
<entity>
<prop></prop>
</entity>
<entity>
<prop></prop>
</entity>
</entities>
That being said, using data binding, the easiest way would be to create another class to wrap a List<Entity>. Now I'm not too familiar with Jackson's XML capabilities/features, but using JAXB, you can have a class like:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Entities {
#XmlElement(name = "entity")
protected List<Entity> entities;
public List<Entity> getEntities() {
if (entities == null) {
entities = new ArrayList<>();
}
return entities;
}
public void setEntities(List<Entity> entities) {
this.entities = entities;
}
}
Then you can unmarshal the below XMl into the Entities class. Here's an update demo to show both json and xml
public class JsonTableDemo {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = "[{\"checked\":false,\"dateposted\":\"2014-10-23T00:00:00\",\"itemnumber\":1,\"quantity\":5,\"stockcheckid\":1}]";
List<Entity> response = mapper.readValue(json,
TypeFactory.defaultInstance().constructCollectionType(
List.class, Entity.class));
RowTableModel jsonModel = new BeanTableModel<>(Entity.class, response);
JTable jsonTable = new JTable(jsonModel) {
#Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
};
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<entities>\n"
+ " <entity>\n"
+ " <checked>false</checked>\n"
+ " <dateposted>2014-10-22T17:00:00-07:00</dateposted>\n"
+ " <itemnumber>1</itemnumber>\n"
+ " <quantity>5</quantity>\n"
+ " <stockcheckid>1</stockcheckid>\n"
+ " </entity>\n"
+ "</entities>";
JAXBContext context = JAXBContext.newInstance(Entities.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Entities entities = (Entities)unmarshaller.unmarshal(new StringReader(xml));
RowTableModel<Entity> xmlModel = new BeanTableModel<>(
Entity.class, entities.getEntities());
JTable xmlTable = new JTable(xmlModel){
#Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
};
JPanel panel = new JPanel(new GridLayout(0, 1));
JPanel jsonPanel = new JPanel(new BorderLayout());
jsonPanel.add(new JLabel("JSON Table", SwingConstants.CENTER), BorderLayout.PAGE_START);
jsonPanel.add(new JScrollPane(jsonTable));
panel.add(jsonPanel);
JPanel xmlPanel = new JPanel(new BorderLayout());
xmlPanel.add(new JLabel("XML Table", SwingConstants.CENTER), BorderLayout.PAGE_START);
xmlPanel.add(new JScrollPane(xmlTable));
panel.add(xmlPanel);
JOptionPane.showMessageDialog(null, new JScrollPane(panel));
}
}
See more about using JAXB
MongoDB seems to return BSON/JSON objects.
I thought that surely you'd be able to retrieve values as Strings, ints etc. which can then be saved as POJO.
I have a DBObject (instantiated as a BasicDBObject) as a result of iterating over a list ... (cur.next()).
Is the only way (other than using some sort of persistence framework) to get the data into a POJO to use a JSON serlialiser/deserialiser?
My method looks like this:
public List<User> findByEmail(String email){
DBCollection userColl;
try {
userColl = Dao.getDB().getCollection("users"); } catch (UnknownHostException e) { e.printStackTrace(); } catch (MongoException e) { e.printStackTrace();}
DBCursor cur = userColl.find();
List<User> usersWithMatchEmail = new ArrayList<User>();
while(cur.hasNext()) {
// this is where I want to convert cur.next() into a <User> POJO
usersWithMatchEmail.add(cur.next());
}
return null;
}
EDIT: It's pretty obvious, just do something like this.
Let Spring do the heavy lifting with the stuff it already has built for this...
The real trick is: mongoTemplate.getConverter().read(Foo.class, obj);
For example, when using a DBCursor -
while (cursor.hasNext()) {
DBObject obj = cursor.next();
Foo foo = mongoTemplate.getConverter().read(Foo.class, obj);
returnList.add(foo);
}
http://revelfire.com/spring-data-mongodb-convert-from-raw-query-dbobject/
There is a few java libs that can help you with it:
Morhpia - http://code.google.com/p/morphia/
Spring Data for MongoDB - http://www.springsource.org/spring-data/mongodb
Though a late answer , someone might find this useful.
I use GSON to convert from BasicDBObject to my own POJO which is TinyBlogDBObject
TinyBlogDBObject obj = convertJSONToPojo(cursor.next().toString());
private static TinyBlogDBObject convertJSONToPojo(String json){
Type type = new TypeToken< TinyBlogDBObject >(){}.getType();
return new Gson().fromJson(json, type);
}
1. Provide MongoDatabase bean with proper CodecRegistry
#Bean
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString("mongodb://username:password#127.0.0.1:27017/dbname");
ConnectionPoolSettings connectionPoolSettings = ConnectionPoolSettings.builder()
.minSize(2)
.maxSize(20)
.maxWaitQueueSize(100)
.maxConnectionIdleTime(60, TimeUnit.SECONDS)
.maxConnectionLifeTime(300, TimeUnit.SECONDS)
.build();
SocketSettings socketSettings = SocketSettings.builder()
.connectTimeout(5, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.build();
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.applyToConnectionPoolSettings(builder -> builder.applySettings(connectionPoolSettings))
.applyToSocketSettings(builder -> builder.applySettings(socketSettings))
.build();
return MongoClients.create(clientSettings);
}
#Bean
public MongoDatabase mongoDatabase(MongoClient mongoClient) {
CodecRegistry defaultCodecRegistry = MongoClientSettings.getDefaultCodecRegistry();
CodecRegistry fromProvider = CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build());
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(defaultCodecRegistry, fromProvider);
return mongoClient.getDatabase("dbname").withCodecRegistry(pojoCodecRegistry);
}
2. Annotate POJOS
public class ProductEntity {
#BsonProperty("name") public final String name;
#BsonProperty("description") public final String description;
#BsonProperty("thumb") public final ThumbEntity thumbEntity;
#BsonCreator
public ProductEntity(
#BsonProperty("name") String name,
#BsonProperty("description") String description,
#BsonProperty("thumb") ThumbEntity thumbEntity) {
this.name = name;
this.description = description;
this.thumbEntity = thumbEntity;
}
}
public class ThumbEntity {
#BsonProperty("width") public final Integer width;
#BsonProperty("height") public final Integer height;
#BsonProperty("url") public final String url;
#BsonCreator
public ThumbEntity(
#BsonProperty("width") Integer width,
#BsonProperty("height") Integer height,
#BsonProperty("url") String url) {
this.width = width;
this.height = height;
this.url = url;
}
}
3. Query mongoDB and obtain POJOS
MongoCollection<Document> collection = mongoDatabase.getCollection("product");
Document query = new Document();
List<ProductEntity> products = collection.find(query, ProductEntity.class).into(new ArrayList<>());
Please check my answer in other post
POJO to org.bson.Document and Vice Versa
You can use GSON library provided by Google. Here is the example of it. There are many other api that you can use to convert json into pojo like jettision api,etc.