I am using jackson library for deserializing json data.
Is there a way to skip some element if a attribute does not fit a criteria?
For Example
The java classes:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Group
{
private String name;
private int id;
private List<User> userList;
}
#JsonIgnoreProperties(ignoreUnknown = true)
public class User
{
private String firstName;
private String lastName;
private boolean deleted;
}
The Json File:
["test.Group", {
"name" : "testgroup1",
"id" : 3
"userList" : [ "java.util.ArrayList", [
["test.User", {
"firstName" : "John",
"lastName" : "Doe",
"deleted" : false } ],
["test.User", {
"firstName" : "John",
"lastName" : "Doe",
"deleted" : true } ],
["test.User", {
"firstName" : "John",
"lastName" : "Doe",
"deleted" : false } ] ] ]
}]
Usually I am deserialzing like this:
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
test.Group g1 = mapper.readValue(jsonString,test.Group.class);
Now, Is it possible to skip every user-element whose attribute "deleted" has value true ?
I there a way to do this with data-bind or do I have to use another method like tree or streaming ?
EDIT
I am developing for android, not desktop.
The reason for this question is, that there can be thousands of User elements and I want to minimize the memory usage.
Not skipping, but removing after reading using Java 8 (assuming your User has a getter for deleted):
g1.getUserList().removeIf(User::isDeleted);
You can inject an intermediary by parsing to a tree node and then filtering on the nodes. An example:
public static void main(String[] args)
{
Group g = new Group();
g.setId(1);
g.setName("Test");
User u1 = new User();
u1.setDeleted(false);
u1.setFirstName("John");
u1.setLastName("Jones");
User u2 = new User();
u2.setDeleted(true);
u2.setFirstName("Jane");
u2.setLastName("Jones");
g.addUser(u1);
g.addUser(u2);
try
{
ObjectMapper mapper = new ObjectMapper();
String jsonVal = mapper.writeValueAsString(g);
JsonNode node = mapper.readTree(jsonVal);
for (Iterator<Entry<String, JsonNode>> it = node.fields(); it.hasNext(); )
{
Map.Entry<String, JsonNode> field = it.next();
String key = field.getKey();
if ("userList".equals(key))
{
JsonNode users = field.getValue();
if (users.isArray())
{
for (Iterator<JsonNode> x = users.iterator(); x.hasNext();)
{
JsonNode entry = x.next();
if (entry.get("deleted").asBoolean())
{
System.out.println("Remove " + entry.get("firstName").asText() + " " + entry.get("lastName").asText());
x.remove();
}
else
{
System.out.println("Don't remove " + entry.get("firstName").asText() + " " + entry.get("lastName").asText());
}
}
}
}
}
Group grp = mapper.treeToValue(node, Group.class);
System.out.println("Final group: " + grp);
}
catch (Exception e)
{
System.out.println("Something went wrong...");
e.printStackTrace();
}
}
Output results in :
Don't remove John Jones
Remove Jane Jones
Final group: Group [name=Test, id=1, userList=[User [firstName=John, lastName=Jones, deleted=false]]]
Here is a second approach using a custom deserializer on the Group object. This is just something I read up on so there may be efficiencies that can be added:
public class Answer28536024 {
#JsonDeserialize(using = GroupDeserializer.class)
public static class Group
{
private String name;
private int id;
private List<User> userList;
public Group()
{
userList = new ArrayList<User>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void addUser(User u)
{
userList.add(u);
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
#Override
public String toString() {
return "Group [name=" + name + ", id=" + id + ", userList=" + userList
+ "]";
}
}
public static class GroupDeserializer extends JsonDeserializer<Group>
{
#Override
public Group deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
Group group = new Group();
group.setName(node.get("name").asText());
group.setId(node.get("id").asInt());
JsonNode users = node.get("userList");
if (users.isArray())
{
for (JsonNode userNode : users)
{
if (!userNode.get("deleted").asBoolean())
{
User user = new User();
user.setFirstName(userNode.get("firstName").asText());
user.setLastName(userNode.get("lastName").asText());
user.setDeleted(false);
group.addUser(user);
}
}
}
return group;
}
}
public static class User
{
private String firstName;
private String lastName;
private boolean deleted;
public User()
{
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public boolean isDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
#Override
public String toString() {
return "User [firstName=" + firstName + ", lastName=" + lastName
+ ", deleted=" + deleted + "]";
}
}
public static void main(String[] args)
{
Group g = new Group();
g.setId(1);
g.setName("Test");
User u1 = new User();
u1.setDeleted(false);
u1.setFirstName("John");
u1.setLastName("Jones");
User u2 = new User();
u2.setDeleted(true);
u2.setFirstName("Jane");
u2.setLastName("Jones");
g.addUser(u1);
g.addUser(u2);
try
{
ObjectMapper mapper = new ObjectMapper();
String jsonVal = mapper.writeValueAsString(g);
System.out.println(jsonVal);
Group grp = mapper.readValue(jsonVal, Group.class);
System.out.println("Final group: " + grp);
}
catch (Exception e)
{
System.out.println("Something went wrong...");
e.printStackTrace();
}
}
}
Output for this one:
{"name":"Test","id":1,"userList":[{"firstName":"John","lastName":"Jones","deleted":false},{"firstName":"Jane","lastName":"Jones","deleted":true}]}
Final group: Group [name=Test, id=1, userList=[User [firstName=John, lastName=Jones, deleted=false]]]
Related
Previously I was reading json data in the following format:
JSON
{
"CreationTime":"2018-01-12T12:32:31",
"Id":"08f81fd7-21f1-48ba-a991-08d559b88cc5",
"Operation":"AddedToGroup",
"RecordType":14,
"UserType":0,
"Version":1,
"Workload":"OneDrive",
"ClientIP":"115.186.129.229",
"UserId":"omaji7#emumbaa10.onmicrosoft.com",
"EventSource":"SharePoint",
"ItemType":"Web"
}
I am reading this json data from a kafka topic and doing some stream processing on it and passing it onto another topic. In processing I have created two json objects, send and received.
Using this code:
final StreamsBuilder builder = new StreamsBuilder();
KStream<String, String> source_o365_user_activity = builder.stream("o365_user_activity");
source_o365_user_activity.flatMapValues(new ValueMapper<String, Iterable<String>>() {
#Override
public Iterable<String> apply(String value) {
System.out.println("========> o365_user_activity_by_date Log: " + value);
ArrayList<String> keywords = new ArrayList<String>();
try {
JSONObject send = new JSONObject();
JSONObject received = new JSONObject(value);
send.put("current_date", getCurrentDate().toString()); // UTC TIME
send.put("activity_time", received.get("CreationTime")); // CONSTANTS FINAL STATIC(Topic Names, Cassandra keys)
send.put("user_id", received.get("UserId"));
send.put("operation_type", received.get("Operation"));
send.put("app_name", received.get("Workload"));
keywords.add(send.toString());
// apply regex to value and for each match add it to keywords
} catch (Exception e) {
// TODO: handle exception
System.err.println("Unable to convert to json");
e.printStackTrace();
}
return keywords;
}
}).to("o365_user_activity_by_date");
This was fairly simple. Now I have a json data with lists in them.
JSON
{
"CreationTime":"2017-12-27T07:47:46",
"Id":"10ee505b-90a4-4ac1-b96f-a6dbca939694",
"Operation":"Add member to role.",
"OrganizationId":"2f88f444-62da-4aae-b8af-8331a6915801",
"RecordType":8,
"ResultStatus":"success",
"UserKey":"10030000A656FE5B#emumbaa10.onmicrosoft.com",
"UserType":0,
"Version":1,
"Workload":"AzureActiveDirectory",
"ObjectId":"mustafa#emumbaa10.onmicrosoft.com",
"UserId":"omaji7#emumbaa10.onmicrosoft.com",
"AzureActiveDirectoryEventType":1,
"ExtendedProperties":[
{
"Name":"Role.ObjectID",
"Value":"b0f54661-2d74-4c50-afa3-1ec803f12efe"
},
{
"Name":"Role.DisplayName",
"Value":"Billing Administrator"
},
{
"Name":"Role.TemplateId",
"Value":"b0f54661-2d74-4c50-afa3-1ec803f12efe"
},
{
"Name":"Role.WellKnownObjectName",
"Value":"BillingAdmins"
}
],
"Actor":[
{
"ID":"omaji7#emumbaa10.onmicrosoft.com",
"Type":5
},
{
"ID":"10030000A656FE5B",
"Type":3
},
{
"ID":"User_d03ca514-adfa-4585-a8bd-7182a9a086c7",
"Type":2
}
],
"ActorContextId":"2f88f444-62da-4aae-b8af-8331a6915801",
"InterSystemsId":"6d402a5b-c5de-4d9f-a805-9371c109e55f",
"IntraSystemId":"a5568d01-f100-497a-b88b-c9731ff31248",
"Target":[
{
"ID":"User_8f77c311-3ea0-4146-9f7d-db21bd052d3d",
"Type":2
},
{
"ID":"mustafa#emumbaa10.onmicrosoft.com",
"Type":5
},
{
"ID":"1003BFFDA67CCA03",
"Type":3
}
],
"TargetContextId":"2f88f444-62da-4aae-b8af-8331a6915801"
}
How can I go about doing the same thing in my Stream processing?
I want to be able to read JSON data against some keys (including the list data keys).
Why not convert JSON to Object and then filter against using the field in Object?
Can't you do like this?
send.put("target_0_id", received.get("Target").getJSONObject(0).get("ID"));
You can use gson library and can convert the json to object and using getter and setter you can build your desired output JSON. You can also parse the input JSON to fetch the JSONArray details. Following is the code how you can do it using POJO.
Input class:
public class Input {
private String UserType;
private String TargetContextId;
private String RecordType;
private String Operation;
private String Workload;
private String UserId;
private String OrganizationId;
private String InterSystemsId;
private ExtendedProperties[] ExtendedProperties;
private String ActorContextId;
private String CreationTime;
private String IntraSystemId;
private Target[] Target;
private Actor[] Actor;
private String Id;
private String Version;
private String ResultStatus;
private String ObjectId;
private String AzureActiveDirectoryEventType;
private String UserKey;
public String getUserType ()
{
return UserType;
}
public void setUserType (String UserType)
{
this.UserType = UserType;
}
public String getTargetContextId ()
{
return TargetContextId;
}
public void setTargetContextId (String TargetContextId)
{
this.TargetContextId = TargetContextId;
}
public String getRecordType ()
{
return RecordType;
}
public void setRecordType (String RecordType)
{
this.RecordType = RecordType;
}
public String getOperation ()
{
return Operation;
}
public void setOperation (String Operation)
{
this.Operation = Operation;
}
public String getWorkload ()
{
return Workload;
}
public void setWorkload (String Workload)
{
this.Workload = Workload;
}
public String getUserId ()
{
return UserId;
}
public void setUserId (String UserId)
{
this.UserId = UserId;
}
public String getOrganizationId ()
{
return OrganizationId;
}
public void setOrganizationId (String OrganizationId)
{
this.OrganizationId = OrganizationId;
}
public String getInterSystemsId ()
{
return InterSystemsId;
}
public void setInterSystemsId (String InterSystemsId)
{
this.InterSystemsId = InterSystemsId;
}
public ExtendedProperties[] getExtendedProperties ()
{
return ExtendedProperties;
}
public void setExtendedProperties (ExtendedProperties[] ExtendedProperties)
{
this.ExtendedProperties = ExtendedProperties;
}
public String getActorContextId ()
{
return ActorContextId;
}
public void setActorContextId (String ActorContextId)
{
this.ActorContextId = ActorContextId;
}
public String getCreationTime ()
{
return CreationTime;
}
public void setCreationTime (String CreationTime)
{
this.CreationTime = CreationTime;
}
public String getIntraSystemId ()
{
return IntraSystemId;
}
public void setIntraSystemId (String IntraSystemId)
{
this.IntraSystemId = IntraSystemId;
}
public Target[] getTarget ()
{
return Target;
}
public void setTarget (Target[] Target)
{
this.Target = Target;
}
public Actor[] getActor ()
{
return Actor;
}
public void setActor (Actor[] Actor)
{
this.Actor = Actor;
}
public String getId ()
{
return Id;
}
public void setId (String Id)
{
this.Id = Id;
}
public String getVersion ()
{
return Version;
}
public void setVersion (String Version)
{
this.Version = Version;
}
public String getResultStatus ()
{
return ResultStatus;
}
public void setResultStatus (String ResultStatus)
{
this.ResultStatus = ResultStatus;
}
public String getObjectId ()
{
return ObjectId;
}
public void setObjectId (String ObjectId)
{
this.ObjectId = ObjectId;
}
public String getAzureActiveDirectoryEventType ()
{
return AzureActiveDirectoryEventType;
}
public void setAzureActiveDirectoryEventType (String AzureActiveDirectoryEventType)
{
this.AzureActiveDirectoryEventType = AzureActiveDirectoryEventType;
}
public String getUserKey ()
{
return UserKey;
}
public void setUserKey (String UserKey)
{
this.UserKey = UserKey;
}
#Override
public String toString()
{
return "ClassPojo [UserType = "+UserType+", TargetContextId = "+TargetContextId+", RecordType = "+RecordType+", Operation = "+Operation+", Workload = "+Workload+", UserId = "+UserId+", OrganizationId = "+OrganizationId+", InterSystemsId = "+InterSystemsId+", ExtendedProperties = "+ExtendedProperties+", ActorContextId = "+ActorContextId+", CreationTime = "+CreationTime+", IntraSystemId = "+IntraSystemId+", Target = "+Target+", Actor = "+Actor+", Id = "+Id+", Version = "+Version+", ResultStatus = "+ResultStatus+", ObjectId = "+ObjectId+", AzureActiveDirectoryEventType = "+AzureActiveDirectoryEventType+", UserKey = "+UserKey+"]";
}}
Target class:
public class Target {
private String Type;
private String ID;
public String getType() {
return Type;
}
public void setType(String Type) {
this.Type = Type;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
#Override
public String toString() {
return "ClassPojo [Type = " + Type + ", ID = " + ID + "]";
}}
Actor class :
public class Actor {
private String Type;
private String ID;
public String getType() {
return Type;
}
public void setType(String Type) {
this.Type = Type;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
#Override
public String toString() {
return "ClassPojo [Type = " + Type + ", ID = " + ID + "]";
}}
ExtendedProperties class :
public class ExtendedProperties {
private String Name;
private String Value;
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getValue() {
return Value;
}
public void setValue(String Value) {
this.Value = Value;
}
#Override
public String toString() {
return "ClassPojo [Name = " + Name + ", Value = " + Value + "]";
}}
Main class :
public class Stack {
public static void main(String[] args) {
doIt();
}
private static void doIt() {
String received = "{\"CreationTime\":\"2017-12-27T07:47:46\",\"Id\":\"10ee505b-90a4-4ac1-b96f-a6dbca939694\",\"Operation\":\"Add member to role.\",\"OrganizationId\":\"2f88f444-62da-4aae-b8af-8331a6915801\",\"RecordType\":8,\"ResultStatus\":\"success\",\"UserKey\":\"10030000A656FE5B#emumbaa10.onmicrosoft.com\",\"UserType\":0,\"Version\":1,\"Workload\":\"AzureActiveDirectory\",\"ObjectId\":\"mustafa#emumbaa10.onmicrosoft.com\",\"UserId\":\"omaji7#emumbaa10.onmicrosoft.com\",\"AzureActiveDirectoryEventType\":1,\"ExtendedProperties\":[{\"Name\":\"Role.ObjectID\",\"Value\":\"b0f54661-2d74-4c50-afa3-1ec803f12efe\"},{\"Name\":\"Role.DisplayName\",\"Value\":\"Billing Administrator\"},{\"Name\":\"Role.TemplateId\",\"Value\":\"b0f54661-2d74-4c50-afa3-1ec803f12efe\"},{\"Name\":\"Role.WellKnownObjectName\",\"Value\":\"BillingAdmins\"}],\"Actor\":[{\"ID\":\"omaji7#emumbaa10.onmicrosoft.com\",\"Type\":5},{\"ID\":\"10030000A656FE5B\",\"Type\":3},{\"ID\":\"User_d03ca514-adfa-4585-a8bd-7182a9a086c7\",\"Type\":2}],\"ActorContextId\":\"2f88f444-62da-4aae-b8af-8331a6915801\",\"InterSystemsId\":\"6d402a5b-c5de-4d9f-a805-9371c109e55f\",\"IntraSystemId\":\"a5568d01-f100-497a-b88b-c9731ff31248\",\"Target\":[{\"ID\":\"User_8f77c311-3ea0-4146-9f7d-db21bd052d3d\",\"Type\":2},{\"ID\":\"mustafa#emumbaa10.onmicrosoft.com\",\"Type\":5},{\"ID\":\"1003BFFDA67CCA03\",\"Type\":3}],\"TargetContextId\":\"2f88f444-62da-4aae-b8af-8331a6915801\"}";
JSONObject send = new JSONObject();
Gson gson = new Gson();
Input inputObject = gson.fromJson(received, Input.class);
// you can add values here and customize the output JSON
send.put("userId", inputObject.getUserId());
send.put("Workload", inputObject.getWorkload());
// read Actor list
Actor[] arr = inputObject.getActor();
for (int i = 0; i < arr.length; i++) {
// write your logic here how you want to handle the Actor list
// values
System.out.println(arr[i].getID() + " : " + arr[i].getType());
}
// read ExtendedProperties list
ExtendedProperties[] extendedProperties = inputObject.getExtendedProperties();
for (int j = 0; j < extendedProperties.length; j++) {
// write your logic here how you want to handle the
// ExtendedProperties list values
System.out.println(extendedProperties[j].getName() + " : " + extendedProperties[j].getValue());
}
System.out.println("*************");
}}
alternate main class without using POJO. Here org.json library have been used to parse the input JSON.
public class Test {
public static void main(String[] args) {
doIt();
}
private static void doIt() {
String received = "{\"CreationTime\":\"2017-12-27T07:47:46\",\"Id\":\"10ee505b-90a4-4ac1-b96f-a6dbca939694\",\"Operation\":\"Add member to role.\",\"OrganizationId\":\"2f88f444-62da-4aae-b8af-8331a6915801\",\"RecordType\":8,\"ResultStatus\":\"success\",\"UserKey\":\"10030000A656FE5B#emumbaa10.onmicrosoft.com\",\"UserType\":0,\"Version\":1,\"Workload\":\"AzureActiveDirectory\",\"ObjectId\":\"mustafa#emumbaa10.onmicrosoft.com\",\"UserId\":\"omaji7#emumbaa10.onmicrosoft.com\",\"AzureActiveDirectoryEventType\":1,\"ExtendedProperties\":[{\"Name\":\"Role.ObjectID\",\"Value\":\"b0f54661-2d74-4c50-afa3-1ec803f12efe\"},{\"Name\":\"Role.DisplayName\",\"Value\":\"Billing Administrator\"},{\"Name\":\"Role.TemplateId\",\"Value\":\"b0f54661-2d74-4c50-afa3-1ec803f12efe\"},{\"Name\":\"Role.WellKnownObjectName\",\"Value\":\"BillingAdmins\"}],\"Actor\":[{\"ID\":\"omaji7#emumbaa10.onmicrosoft.com\",\"Type\":5},{\"ID\":\"10030000A656FE5B\",\"Type\":3},{\"ID\":\"User_d03ca514-adfa-4585-a8bd-7182a9a086c7\",\"Type\":2}],\"ActorContextId\":\"2f88f444-62da-4aae-b8af-8331a6915801\",\"InterSystemsId\":\"6d402a5b-c5de-4d9f-a805-9371c109e55f\",\"IntraSystemId\":\"a5568d01-f100-497a-b88b-c9731ff31248\",\"Target\":[{\"ID\":\"User_8f77c311-3ea0-4146-9f7d-db21bd052d3d\",\"Type\":2},{\"ID\":\"mustafa#emumbaa10.onmicrosoft.com\",\"Type\":5},{\"ID\":\"1003BFFDA67CCA03\",\"Type\":3}],\"TargetContextId\":\"2f88f444-62da-4aae-b8af-8331a6915801\"}";
JSONObject send = new JSONObject();
JSONObject input = new JSONObject(received);
// you can add values here and customize the output JSON
send.put("userId", input.getString("UserId"));
send.put("Workload", input.getString("Workload"));
// read Actor list
JSONArray actorArray = input.getJSONArray("Actor");
for (int i = 0; i < actorArray.length(); i++) {
// write your logic here how you want to handle the Actor list
// values
System.out.println(
actorArray.getJSONObject(i).getString("ID") + ":" + actorArray.getJSONObject(i).getInt("Type"));
}
// read ExtendedProperties list
JSONArray extendedProperties = input.getJSONArray("ExtendedProperties");
for (int j = 0; j < extendedProperties.length(); j++) {
// write your logic here how you want to handle the
// ExtendedProperties list values
System.out.println(extendedProperties.getJSONObject(j).getString("Name") + " : "
+ extendedProperties.getJSONObject(j).getString("Value"));
}
System.out.println("*************");
}}
I have some input values like this:
customername
phone
email
.....
some items values
itemname1
itemname2
........
In every item name have some unitprice
quantity
........
I'm trying to encode these values in json like this:
{
"info": {
"customername": "abc",
"phone": "123",
"email": "an#gmail.com",
},
"item": {
"itemname1": {
"unitprice": "100",
"qty": "3",
},
"itemname2": {
"unitprice": "500",
"qty": "2",
}
}
}
I 'm unable to encode all value like above.
here is my code:
private void jsonEncoding() throws JSONException {
JSONObject obj = new JSONObject();
JSONObject obj1 = new JSONObject();
JSONObject obj2 = new JSONObject();
try {
obj1.put("name", name);
obj1.put("email", email);
obj1.put("phone", phone);
} catch (JSONException e) {
e.printStackTrace();
}
obj.put("info",obj1 );
System.out.print(obj);
System.out.print(obj1);
}
How to encode values like above json format.
You can do it in 2 ways:
Using 3rd party libraries like Gson/Jackson for converting the POJO class data to json object string (use http://www.jsonschema2pojo.org/ for creating POJO class easily)
Manually do JsonParsing like below:
try {
// info node
JSONObject objInfo = new JSONObject();
objInfo.put("name", name);
objInfo.put("email", email);
objInfo.put("phone", phone);
// itemname1 node
JSONObject itemname1 = new JSONObject();
itemname1.put("unitprice", unitprice1);
itemname1.put("qty", qty1);
// itemname2 node
JSONObject itemname2 = new JSONObject();
itemname2.put("unitprice", unitprice2);
itemname2.put("qty", qty2);
// item node
JSONObject item = new JSONObject();
// adding itemname1 & itemname2 to item
item.put("itemname1",itemname1);
item.put("itemname2",itemname2);
// root node
JSONObject root = new JSONObject();
root.put("info",objInfo);
root.put("item",item);
System.out.print(root);
} catch(JsonException e){
e.printStackTrace();
}
Create a POJO class similar to your response
class Info {
String customerName;
String phone;
String email;
}
class ItemName{
String unitprice;
String qty;
}
class Item{
ItemName itemname1;
ItemName itemname2;
}
class Data{
Info info;
Item item;
}
Now just use google gson library to convert instance of Data to json as in
new Gson().toJson(data);
Try this it may help
You need to create three classes and as your using Gson means you are going with networking feature hence implement serializable for all like below.
class CustomObject implements Serializable {
Info info;
Map<String, ItemName> item;
public CustomObject() {
this(null, null);
}
public CustomObject(Info info, Map<String, ItemName> item) {
this.info = info;
this.item = item;
}
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
public Map<String, ItemName> getItem() {
return item;
}
public void setItem(Map<String, ItemName> item) {
this.item = item;
}
}
class Info implements Serializable {
String customername;
String phone;
String email;
public Info() {
this("","","");
}
public Info(String customername, String phone, String email) {
this.customername = customername;
this.phone = phone;
this.email = email;
}
public String getCustomername() {
return customername;
}
public void setCustomername(String customername) {
this.customername = customername;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
class ItemName implements Serializable {
String unitprice;
String qty;
public ItemName() {
this("", "");
}
public ItemName(String unitprice, String qty) {
this.unitprice = unitprice;
this.qty = qty;
}
public String getUnitprice() {
return unitprice;
}
public void setUnitprice(String unitprice) {
this.unitprice = unitprice;
}
public String getQty() {
return qty;
}
public void setQty(String qty) {
this.qty = qty;
}
}
Now You Have to add your data as per need like below.
CustomObject customObject = new CustomObject();
Info info = new Info();
info.setCustomername("abc");
info.setPhone("123");
info.setEmail("an#gmail.com");
customObject.setInfo(info);
ItemName itemname1 = new ItemName();
itemname1.setUnitprice("100");
itemname1.setQty("3");
ItemName itemname2 = new ItemName();
itemname2.setUnitprice("500");
itemname2.setQty("2");
Map<String, ItemName> item = new HashMap<>();
item.put("itemname1", itemname1);
item.put("itemname2", itemname2);
customObject.setItem(item);
System.out.println(new Gson().toJson(customObject));
Above System.out.println gives output as
{
"info":
{
"customername":"abc",
"phone":"123",
"email":"an#gmail.com"},
"item":{
"itemname1":
{
"unitprice":"100",
"qty":"3"
},
"itemname2":
{
"unitprice":"500",
"qty":"2"
}
}
}
Now how to parse your string which you got from server or any source to that CustomObject class. Its very simple through Gson library by google.
String str = "{\n" +
" \"info\":\n" +
" {\n" +
" \"customername\":\"abc\",\n" +
" \"phone\":\"123\",\n" +
" \"email\":\"an#gmail.com\"\n" +
" },\n" +
" \"item\": \n" +
" {\n" +
" \"itemname1\":\n" +
" {\n" +
" \"unitprice\":\"100\",\n" +
" \"qty\":\"3\"\n" +
" },\n" +
" \"itemname2\":\n" +
" {\n" +
" \"unitprice\":\"500\",\n" +
" \"qty\":\"2\"\n" +
" }\n" +
" }\n" +
" }";
CustomObject customObject = new Gson().fromJson(str, new TypeToken<CustomObject>(){}.getType());
System.out.println(new Gson().toJson(customObject));
This question already has answers here:
a field name "ClassName" is being inserted into mongodb by morphia
(2 answers)
Closed 6 years ago.
I am using Morphia (http://mongodb.github.io/morphia/1.2/getting-started/quick-tour/) to try out a sample CRUD application in Java + MongoDB. I tried inserting some documents in the collection (user) and it worked fine, however i see an extra field ("className" : "com.study.mongodb.User") getting inserted in my collection which I do not want.
user: collection data
/* 1 */
{
"_id" : ObjectId("57dabf8be273f32fecf6e6cd"),
"className" : "com.study.mongodb.User",
"firstName" : "Alex",
"lastName" : "Foo",
"birthDate" : Date(60237752400000),
"hasPremiumAccess" : true
}
/* 2 */
{
"_id" : ObjectId("57dabf8be273f32fecf6e6ce"),
"className" : "com.study.mongodb.User",
"firstName" : "Sacha",
"lastName" : "Foo",
"birthDate" : Date(60564859200000),
"hasPremiumAccess" : false
}
Main.java
public class Main {
private final Datastore ds;
private final UserDAO userDAO;
public Main() {
this.ds = new MorphiaService().getDatastore();
this.userDAO = new UserDAOImpl(User.class, ds);
}
public static void main(String[] args) {
Main m = new Main();
//drop collection every time to prevent duplicate record insertion thru below method
m.dropCollection();
//save user
m.saveUsers();
//get user(s)
m.displayAllUsers();
m.displayUserByFirstAndLastName();
//update user(s)
//delete user(s)
}
private void dropCollection() {
ds.getDB().getCollection("user").drop();
}
public void saveUsers() {
System.out.println("\n***************Save user example***************");
User user1 = new User("Alex", "Foo", new Date(1978, 10, 10), true);
User user2 = new User("Sacha", "Foo", new Date(1989, 2, 23), false);
userDAO.save(user1);
userDAO.save(user2);
System.out.println("After persist:");
System.out.println("User1 objectId = " + user1.getObjectId());
System.out.println("User2 objectId = " + user2.getObjectId());
}
}
MorphiaService.java
public class MorphiaService {
private static final String HOST_NAME = "gsi-547576";
private static final int PORT = 27017;
private static final String DB_NAME = "test";
private Morphia morphia;
private Datastore datastore;
public MorphiaService() {
MongoClient mongoClient = new MongoClient(HOST_NAME, PORT);
morphia = new Morphia();
morphia.mapPackage("org.study.crud.domain");
datastore = morphia.createDatastore(mongoClient, DB_NAME);
}
public Morphia getMorphia() {
return morphia;
}
public void setMorphia(Morphia morphia) {
this.morphia = morphia;
}
public Datastore getDatastore() {
return datastore;
}
public void setDatastore(Datastore datastore) {
this.datastore = datastore;
}
}
UserDAOImpl.java
public class UserDAOImpl extends BasicDAO<User, ObjectId> implements UserDAO {
public UserDAOImpl(Class<User> entityClass, Datastore ds) {
super(entityClass, ds);
}
#Override
public List<User> getAllUsers() {
final Query<User> query = ds.createQuery(User.class);
final List<User> users = query.asList();
return users;
}
#Override
public User getByFirstNameLastName(String firstName, String lastName) {
Query<User> query = createQuery().field("firstName").equal(firstName).field("lastName").equal(lastName);
return query.get();
}
}
User.java
#Entity("user")
public class User {
#Id
private ObjectId objectId;
private String firstName;
private String lastName;
private Date birthDate;
private boolean hasPremiumAccess;
/**
* keep an empty constructor so that morphia can recreate this entity when you want to fetch it from the database
*/
public User() {
}
/**
* full constructor (without objectId, we let morphia generate this one for us)
*
* #param firstName
* #param lastName
* #param birthDate
* #param hasPremiumAccess
*/
public User(String firstName, String lastName, Date birthDate, boolean hasPremiumAccess) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDate = birthDate;
this.hasPremiumAccess = hasPremiumAccess;
}
public ObjectId getObjectId() {
return objectId;
}
public void setObjectId(ObjectId objectId) {
this.objectId = objectId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public boolean isHasPremiumAccess() {
return hasPremiumAccess;
}
public void setHasPremiumAccess(boolean hasPremiumAccess) {
this.hasPremiumAccess = hasPremiumAccess;
}
#Override
public String toString() {
return "User{" + "objectId=" + objectId + ", firstName=" + firstName + ", lastName=" + lastName + ", birthDate=" + birthDate + ", hasPremiumAccess=" + hasPremiumAccess + '}';
}
}
Why is this field with 'className' getting inserted in the collection?
I tried to reproduce this scenario. We can disable this behaviour using below annotation.
#Entity(value = "user", noClassnameStored = true)
Regards,
Sanjay Reddy
I have created a graph database as hierarchical tree as a result of converting a MySQL database in another Neo4j database. The transformation worked fine.
On the top level exist a node labeled as Root, on the second level are the countries labeled as Country. Every country has cities that is the third level labeled as City. And down for every city there are a subset of addresses labeled as Address. The relationships should be,
(root)-[:IS_ROOT]->(country)-[:HAS_CITY]->(city)-[:HAS_ADDRESS]->(address)
Later, using Spring Data Neo4j repositories, I tried to query the database with no result.
For the MySQL database I use JDBC, and for the Neo4j database I use Spring Data Neo4j as mentioned before.
This is the controller I use to create the Neo4j database,
#Controller("importer")
public class SakilaDbImportController {
private static final Logger logger = LoggerFactory.getLogger(SakilaDbImportController.class);
#Autowired
#Lazy
AddressNeoRepository addressRepo;
#Autowired
#Lazy
CityNeoRepository cityRepo;
#Autowired
#Lazy
CountryNeoRepository countryRepo;
#Autowired
#Lazy
RootRepository rootRepo;
#Autowired
Neo4jTemplate template;
#Autowired
SakilaDbApiClient client;
public SakilaDbImportController() {
}
#Transactional
public RootNeo createGraphDb() {
RootNeo root = doImportRoot();
return root;
}
#Transactional
public RootNeo importRoot() {
return doImportRoot();
}
private RootNeo doImportRoot() {
logger.debug("Importing root");
RootNeo root = new RootNeo("1", "Root");
root.addLabel("_Root");
//root.addLabel("Root");
System.out.println("root created " + root);
List<Country> data = client.readAllCountries();
if (data.isEmpty()) throw new RuntimeException("Data for Root not found.");
Map<CountryNeo, RoleIsRoot> roles = relateCountriesToRoot(root, data);
//template.save(root);
Set<CountryNeo> set = roles.keySet();
for(Iterator<CountryNeo> it = set.iterator(); it.hasNext();) {
root.isRoot(it.next());
}
rootRepo.save(root);
/*
for(RoleIsRoot role: roles){
template.save(role);
}
*/
return root;
}
private Map<CountryNeo, RoleIsRoot> relateCountriesToRoot(RootNeo root, List<Country> data) {
Map<CountryNeo, RoleIsRoot> roles = new HashMap<CountryNeo, RoleIsRoot>();
for (Country country : data) {
if(country.getCountry().equalsIgnoreCase("Canada"))
continue;
CountryNeo countryNeo = doImportCountryNeo(country);
RoleIsRoot role = root.isRoot(countryNeo, "IS_ROOT_OF");
System.out.println("RoleIsRoot: " + role);
roles.put(countryNeo, role);
}
return roles;
}
#Transactional
public CountryNeo importCountryNeo(Country country) {
return doImportCountryNeo(country);
}
private CountryNeo doImportCountryNeo(Country country) {
logger.debug("Importing countryNeo");
CountryNeo countryNeo = new CountryNeo(generateIndex(country.getCountryId()), country.getCountry());
countryNeo.addLabel("_Country");
//countryNeo.addLabel("Country");
System.out.println("new country: " + countryNeo);
List<City> data = client.readAllCitiesByCountry(country);
if (data.isEmpty()) throw new RuntimeException("Data for Country not found.");
Map<CityNeo, RoleHasCity> roles = relateCitiesToCountry(countryNeo, data);
Set<CityNeo> set = roles.keySet();
for(Iterator<CityNeo> it = set.iterator(); it.hasNext();) {
countryNeo.hasCity(it.next());
}
countryRepo.save(countryNeo);
/*
template.save(countryNeo);
for(RoleHasCity role: roles){
template.save(role);
}
*/
return countryNeo;
}
private Map<CityNeo, RoleHasCity> relateCitiesToCountry(CountryNeo countryNeo, List<City> data) {
Map<CityNeo, RoleHasCity> roles = new HashMap<CityNeo, RoleHasCity>();
for (City city : data) {
CityNeo cityNeo = doImportCityNeo(city);
RoleHasCity role = countryNeo.hasCity(cityNeo, "IS_CITY_FROM");
System.out.println("RoleHasCity: " + role);
roles.put(cityNeo, role);
}
return roles;
}
#Transactional
public CityNeo importCityNeo(City city) {
return doImportCityNeo(city);
}
private CityNeo doImportCityNeo(City city) {
logger.debug("Importing cityNeo");
CityNeo cityNeo = new CityNeo(generateIndex(city.getCityId()), city.getCity());
cityNeo.addLabel("_City");
//cityNeo.addLabel("City");
System.out.println("new city: " + cityNeo);
List<Address> data = client.readAllAddressesByCity(city);
if (data.isEmpty()) throw new RuntimeException("Data for City not found.");
Map<AddressNeo, RoleHasAddress> roles = relateAddressesToCity(cityNeo, data);
Set<AddressNeo> set = roles.keySet();
for(Iterator<AddressNeo> it = set.iterator(); it.hasNext();) {
cityNeo.hasAddress(it.next());
}
cityRepo.save(cityNeo);
/*
template.save(cityNeo);
for(RoleHasAddress role: roles){
template.save(role);
}
*/
return cityNeo;
}
private Map<AddressNeo, RoleHasAddress> relateAddressesToCity(CityNeo cityNeo, List<Address> data) {
Map<AddressNeo, RoleHasAddress> roles = new HashMap<AddressNeo, RoleHasAddress>();
for(Address address: data) {
AddressNeo addressNeo = doImportAddressNeo(address);
RoleHasAddress role = cityNeo.hasAddress(addressNeo, "IS_ADDRESS_IN");
System.out.println("RoleHasAddress: " + role);
roles.put(addressNeo, role);
}
return roles;
}
#Transactional
public AddressNeo importAddressNeo(Address address) {
return doImportAddressNeo(address);
}
private AddressNeo doImportAddressNeo(Address address) {
logger.debug("Importing addressNeo");
if (address == null) throw new RuntimeException("Address not found.");
AddressNeo addressNeo = new AddressNeo(generateIndex(address.getAddressId()), address.getAddress());
addressNeo.addLabel("_Address");
//addressNeo.addLabel("Address");
System.out.println("new address: " + addressNeo);
addressNeo.setPostalCode(address.getPostalCode());
addressRepo.save(addressNeo);
/*
template.save(addressNeo);
*/
return addressNeo;
}
private String generateIndex(int index) {
return String.valueOf(index);
}
}
And this is the service that, using the repositories, does the queries,
#Service
public class SakilaDbQueries {
#Autowired
#Lazy
AddressNeoRepository addressRepo;
#Autowired
#Lazy
CityNeoRepository cityRepo;
#Autowired
#Lazy
CountryNeoRepository countryRepo;
#Autowired
#Lazy
RootRepository rootRepo;
public SakilaDbQueries() {
}
public List<String> findAllCountryNames() {
CountryNeoData names = countryRepo.findAllCountryNames();
Collection<String> collection = names.getCountries();
List<String> list = new ArrayList<String>();
for(Iterator<String> it = collection.iterator(); it.hasNext(); ) {
list.add(it.next());
}
return list;
}
public List<CountryNeo> findAllCountries() {
Result<CountryNeo> result = countryRepo.findAll();
List<CountryNeo> list = new ArrayList<CountryNeo>();
for(Iterator<CountryNeo> it = result.iterator(); it.hasNext(); ) {
list.add(it.next());
}
return list;
}
}
And as an example,
Here is the NodeEntity Place as generic one,
#NodeEntity
public class Place {
#GraphId Long nodeId;
#Indexed(unique=true)
String id;
#Indexed(indexType=IndexType.FULLTEXT, indexName = "place")
String name;
#Labels
private Collection<String> labels = Collections.emptySet();
protected Place(String id, String name) {
this.id = id;
this.name = name;
}
protected Place() {
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addLabel(String label) {
HashSet<String> newLabels = new HashSet<>(this.labels);
if (newLabels.add(label)) this.labels = newLabels;
}
public void removeLabel(String label) {
HashSet<String> newLabels = new HashSet<>(this.labels);
if (newLabels.remove(label)) this.labels = newLabels;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Place place = (Place) o;
if (nodeId == null) return super.equals(o);
return nodeId.equals(place.nodeId);
}
#Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
#Override
public String toString() {
return String.format("%s [%s]", name, id);
}
}
and CountryNeo that extends Place,
#NodeEntity
public class CountryNeo extends Place {
#RelatedTo(type = "HAS_CITY", direction = Direction.OUTGOING)
Set<CityNeo> cities;
#Fetch #RelatedToVia(type = "IS_ROOT", direction = Direction.INCOMING)
Iterable<RoleIsRoot> roles;
public CountryNeo() {
}
public CountryNeo(String id, String name) {
super(id, name);
}
public Set<CityNeo> getCities() {
return cities;
}
public void hasCity(CityNeo city) {
if(cities == null)
cities = new HashSet<CityNeo>();
cities.add(city);
}
public RoleHasCity hasCity(CityNeo city, String roleName) {
return new RoleHasCity(this, city, roleName);
}
public Collection<RoleIsRoot> getRoles() {
Iterable<RoleIsRoot> allRoles = roles;
return allRoles == null ? Collections.<RoleIsRoot>emptyList() : IteratorUtil.asCollection(allRoles);
}
}
The used roles,
#RelationshipEntity(type = "HAS_CITY")
public class RoleHasCity {
#GraphId Long id;
#StartNode CountryNeo country;
#EndNode CityNeo city;
String name;
public RoleHasCity() {
}
public RoleHasCity(CountryNeo country, CityNeo city, String roleName) {
this.country = country;
this.city = city;
this.name = roleName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CountryNeo getCountry() {
return country;
}
public void setCountry(CountryNeo country) {
this.country = country;
}
public CityNeo getCity() {
return city;
}
public void setCity(CityNeo city) {
this.city = city;
}
#Override
public String toString() {
return String.format("%s %s %s", city, name, country);
}
}
And the repository,
public interface CountryNeoRepository extends GraphRepository<CountryNeo> {
#Query("MATCH (n:CountryNeo) RETURN COLLECT(n.name) AS countries")
CountryNeoData findAllCountryNames();
#QueryResult
public class CountryNeoData {
Collection<String> countries = Collections.emptyList();
public Collection<String> getCountries() {
return countries;
}
}
}
And here is the main bean,
public class SakilaImporter {
private GraphDatabaseService graphDatabase;
private SakilaDbImportController importer;
private SakilaDbQueries queries;
public SakilaImporter(GraphDatabaseService graphDatabase,
SakilaDbImportController importer,
SakilaDbQueries queries) {
this.graphDatabase = graphDatabase;
this.importer = importer;
this.queries = queries;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
GraphDatabaseService graphDatabase = ctx.getBean("graphDatabaseService", GraphDatabaseService.class);
SakilaDbImportController importer = ctx.getBean("importer", SakilaDbImportController.class);
SakilaDbQueries queries = ctx.getBean("queries", SakilaDbQueries.class);
SakilaImporter sakilaImporter = new SakilaImporter(graphDatabase, importer, queries);
Transaction tx = graphDatabase.beginTx();
try {
sakilaImporter.createDatabase();
sakilaImporter.queryDatabase();
tx.success();
} finally {
tx.close();
}
ctx.close();
}
public void createDatabase() {
System.out.println("Importing data...");
final long start = System.currentTimeMillis();
RootNeo root = importer.createGraphDb();
if(root != null) {
final long time = System.currentTimeMillis() - start;
System.out.println("Import places took " + time + " ms.");
} else {
System.out.println("root: " + root);
}
}
public void queryDatabase() {
System.out.println();System.out.println();
System.out.println("List of countries.-");
List<CountryNeo> countries = queries.findAllCountries();
for(CountryNeo country: countries) {
System.out.println(country);
}
System.out.println();System.out.println();
System.out.println("List of country names.-");
List<String> names = queries.findAllCountryNames();
for(String name: names) {
System.out.println(name);
}
}
}
The result of both queries is an empty list
spring 2.5.6
spring framework 4.0.0.RELEASE
neo4j 2.1.8
spring data neo4j 3.1.2.RELEASE
I am using Spring Social FqlQuery to get data's from facebook. Here is the JSON response I am getting from facebook. My controller where i am getting Json output is here,
fql = "SELECT work FROM user WHERE uid = me()";
facebook.fqlOperations().query(fql, new FqlResultMapper<Object>() {
public Object mapObject(FqlResult result) {
List list = (List) result.getObject("work");
for (Object object : list) {
JsonHelper jsonHelper = new JsonHelper();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(object);
System.out.println(jsonOutput);
gson.fromJson(jsonOutput, JsonHelper.class);
}
System.out.println inside for loop Outputs multiple json as below.:
{
"employer": {
"id": 129843057436,
"name": "www.metroplots.com"
},
"location": {
"id": 102186159822587,
"name": "Chennai, Tamil Nadu"
},
"position": {
"id": 108480125843293,
"name": "Web Developer"
},
"start_date": "2012-10-01",
"end_date": "2013-05-31"
}
{
"employer": {
"id": 520808381292985,
"name": "Federation of Indian Blood Donor Organizations"
},
"start_date": "0000-00",
"end_date": "0000-00"
}
Here is my Helper Class:
import java.util.List;
public class JsonHelper {
class Employer{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Location{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Position{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//Edited After here
private String start_Date;
private String end_Date;
private Employer employer;
private Location location;
private Position position;
public String getStart_Date() {
return start_Date;
}
public void setStart_Date(String start_Date) {
this.start_Date = start_Date;
}
public String getEnd_Date() {
return end_Date;
}
public void setEnd_Date(String end_Date) {
this.end_Date = end_Date;
}
public Employer getEmployer() {
return employer;
}
public void setEmployer(Employer employer) {
this.employer = employer;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
}
When I try to convert the json objects to java object as done above I am getting this exception.
HTTP Status 500 - Request processing failed; nested exception is com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 6 column 16
Can any one help me where I am wrong. Please help me converting json to java objects. Hope my question is clear. Thanks in advance.
EDIT MADE TO CONTROLLER:
facebook.fqlOperations().query(fql, new FqlResultMapper<Object>() {
public Object mapObject(FqlResult result) {
List<JsonHelper> json = new ArrayList<JsonHelper>();
List list = (List) result.getObject("work");
for (Object object : list) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(object);
System.out.println(jsonOutput);
JsonHelper jsonHelper = gson.fromJson(jsonOutput, JsonHelper.class);
json.add(jsonHelper);
System.out.println(jsonHelper.getStart_Date());
}
for (JsonHelper jsonHelper : json) {
System.out.println(jsonHelper.getStart_Date());
}
return list;
}
});
Since i am not having the actual api access, so i am trying it with static value in the example. Firstly in your JsonHelper class, replace all int by long , as the values mentioned in the json are of type long and String. Then try it like mentioned below:
String str = "{\n"
+ " \"employer\": {\n"
+ " \"id\": 129843057436,\n"
+ " \"name\": \"www.metroplots.com\"\n"
+ " },\n"
+ " \"location\": {\n"
+ " \"id\": 102186159822587,\n"
+ " \"name\": \"Chennai, Tamil Nadu\"\n"
+ " },\n"
+ " \"position\": {\n"
+ " \"id\": 108480125843293,\n"
+ " \"name\": \"Web Developer\"\n"
+ " },\n"
+ " \"start_date\": \"2012-10-01\",\n"
+ " \"end_date\": \"2013-05-31\"\n"
+ "}";
List<JsonHelper> json = new ArrayList<JsonHelper>();
Gson gson = new Gson();
JsonHelper users = gson.fromJson(str, JsonHelper.class);
json.add(users);
for (JsonHelper js_obj : json) {
System.out.println(js_obj.getEmployer().getId());
System.out.println(js_obj.getEmployer().getName());
}