I have this model in the database
A Country has many States, which has many Cities, which each has a Mayor . The bold being independent tables with ref keys to all They are also Java Classes/Models.
I'd like to construct a JSON in this format for a JS library
{
"Country1": [
"State1":[
"City1":[
"Mr.Mayor"
]
"City2":[
"Mrs.Mayor"
]
],
"State2": [
"City1":[
"Mr.Mayor"
]
.....
Currently implemented as a query that joins all of them into one list of all Countries and their states and cities. Then while looping over the result set from the query construct the above JSON. What is the best/fastest way? I am not using an ORM or JPA but MVC and queries are in DAO
Try building a Multimap<Country, Multimap<State, Map<City, Mayor>>>. Be careful to use the correct types while serializing and deserializing. For example, if you are using Gson, you will need to use the TypeToken class.
Related
I am trying to create a JSON object in Java. Object structure looks like this:
{
"a" : {
"b" : {
"c" : {
"d" : [ {
"value" : false
} ]
}
},
"id" : "123"
},
"type" : "test"
}
I am using com.fasterxml.jackson.databind.ObjectMapper and usually I just create a corresponding domain objects that can be converted to JSON string using ObjectMapper.writeValueAsString() method.
The problem is that in order to match the JSON structure above I will have to create a bunch of domain objects with only one field and on top of that creating a complete JSON object will involve a lot of boilerplate code just to set 2 or 3 JSIN properties.
I am wondering if there is a better approach that I am not familiar with. Maybe, using JSONPath or another library.
Gson (com.google.gson) allows to register custom Serializer, Deserializers and TypeAdapters, with which you can handle a structure without boilerplate classes. This allows for a better conversion from JSON-DTOs to your actual Domain Objects.
See here for an example: https://www.baeldung.com/gson-deserialization-guide
(I'm also quite interested in additional answers to this question.)
I have a JSON string as follows:
{
"account": "1234",
"type": "ar-type",
"eventTypes": "Update",
"objectClassName": "com.triype",
"objectJson": "{\"Name\":\"pdpot\",\"traptype\":\"adpot",\"displayName\":\"pdpot",\"experimentName\":\"pdpotpie\",\"creationTime\":\"Mar 18, 2020 5:58:58 PM\",\"createdBy\":{\"userProfileOne\":\"s:pdx\",\"userProfileTwo\":\"sid\",\"domainId\":\"did:pdx-tod-64003\"},\"lastModifiedBy\":{\"userProfileArn\":\"s:pdx-tod-64003\"},\"createdBy\":{\"userProfileOne\":\"s:p\",\"userProfileTwo\":\"si\",\"domainId\":\"did:ppot\"}}}
}
I get this input as a string and before passing it as a string to a parser I need to perform some string filtering and remove all "userProfileOne", "userProfileTwo","domainId" and their keys, without compromising the JSON structure. I am currently writing this code in Java using gson and json.
Note: There are multiple occurences of UserProfileOne, UserProfileTwo and DomainID.
The required Output is as follows:
{
"account": "1234",
"type": "ar-type",
"eventTypes": "Update",
"objectClassName": "com.triype",
"objectJson": "{\"Name\":\"pdpot\",\"traptype\":\"adpot",\"displayName\":\"pdpot",\"experimentName\":\"pdpotpie\",\"creationTime\":\"Mar 18, 2020 5:58:58 PM\"}}
}
Currently I am using substringBetween. But the operation does not work as intended.
A potential approach is to deserialize the json into a java structure then filter this structure by set to null fields you don't want to be serialize.
By using framework like Jackson you can set this before serialization on the ObjectMapper
mapper.setSerializationInclusion(Include.NON_NULL). So all null values won't be serialized in the final json/result.
I think the best maintainable way would be to create a class structure corresponding to that json and map it to the class.
Use #JsonIgnore on the fields to be ignored and then map it back to JSON from the class structure.
Another approach, a bit complex to implement, is to go through each node in the json and remove that node if it's not required
You can also do it by string matching but I don't think that is a good approach.
With Relational Databases, I could create a model in Java since I know How many columns a table has and their respective names.
But MongoDb doesn't work often with such static schema(If I'm not wrong). So, I want to create a model in Java that hold all the data and convert it into JSON and sent it to the response as a web service.
But I could do by returning just Document or DBObject objects. But It's converting ID as
"_id": {
"timestamp": 1505194179,
"machineIdentifier": 13503772,
"processIdentifier": 3816,
"counter": 1819499,
"date": 1505194179000,
"time": 1505194179000,
"timeSecond": 1505194179
}
Where I just need an ID value for further to make network calls to use this identifier.
So I want to know a best practice or strategy in order to achieve this. I use spring boot.
I'me very much new to Mongodb with Spring boot. So, bear me If my understanding is wrong.
Edit: In Spring boot, it's necessary to define entity class to access the data but I just want to know other way where I don't want a model to be predefined but it should be dynamic as the schema in mongodb.
I've got an object design question.
I'm building a json api in Java. My system uses pojos to represent json objects and translates them from json to pojo using Jackson. Each object needs to take different forms in different contexts, and I can't decide whether to create a bunch of separate classes, one for each context, or try to make a common class work in all circumstances.
Let me give a concrete example.
The system has users. The api has a service to add, modify and delete uses. There is a table of users in a database. The database record looks like this:
{
id: 123, // autoincrement
name: "Bob",
passwordHash: "random string",
unmodifiable: "some string"
}
When you POST/add a user, your pojo should not include an id, because that's autogenerated. You also want to be able to include a password, which gets hashed and stored in the db.
When you PUT/update a user, your pojo shouldn't include the unmodifiable field, but it must include the id, so you know what user you're modifying.
When you GET/retrieve the user, you should get all fields except the passwordHash.
So the pojo that represents the user has different properties depending on whether you're adding, updating, or retrieving the user. And it has different properties in the database.
So, should I create four different pojos in my system and translate among them? Or create one User class and try to make it look different in different circumstances, using Jackson views or some other mechanism?
I'm finding the latter approach really hard to manage.
In my opinion you should create only one POJO - User which has all needed properties. And now you should decide whether your API is rigorous or lenient. If your API is rigorous it should return error when it receives wrong JSON data. In lenient version API can skip superfluous (unnecessary) properties.
Before I will provide an example, let me change the 'passwordHash' property to 'password'.
Add new user/POST
JSON data from client:
{
id: 123,
name: "Bob",
password: "random string",
unmodifiable: "some string"
}
Rigorous version can return for example something like this:
{
"status": "ERROR",
"errors": [
{
"errorType": 1001,
"message": "Id field is not allowed in POST request."
}
]
}
Lenient version can return for example something like this:
{
"status": "SUCCESS",
"warnings": [
"Id field was omitted."
]
}
For each CRUD method you can write a set of unit tests which will be holding information which way you choose and what is allowed and what is not.
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;
}