GSON getting arrays [duplicate] - java

I have a basic JSON with all data contained in an array. One would think that it would be simple to retreive a value out of the array, but after multiple hours of trying every different method of parsing I could think of I'm completely lost. Any help would be greatly appreciated. Sorry for the horrid wording of this question.
I know I've attempted reading the JSON as an object using JsonReader and then parsing for the ID field. That would be my latest attempt, the code for the other attempts has already been deleted I'm afraid and I can't provide much information on said attempts
JsonReader reader = new JsonReader(new FileReader(Constants.VersJson));
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
reader.beginArray();
if (name.equals("id")) {
System.out.println(reader.nextString());
Below I'll include a snippet of the JSON Array.
"versions": [
{
"id": "2.7",
"time": "2012-10-25T15:00:00+02:00",
"releaseTime": "2013-10-25T15:00:00+02:00",
"type": "Release"
},
{
"id": "2.6.4",
"time": "2011-12-2T14:01:07+02:00",
"releaseTime": "2013-12-2T14:01:07+02:00",
"type": "Develop"
},
{
"id": "2.5",
"time": "2010-11-24T21:05:00+02:00",
"releaseTime": "2013-11-25T01:04:05+02:00",
"type": "Develop"

Your json format is not correct which you have posted here
correct it for example
{
"versions":[
{
"id":"2.7",
"time":"2012-10-25T15:00:00+02:00",
"releaseTime":"2013-10-25T15:00:00+02:00",
"type":"Release"
},
{
"id":"2.6.4",
"time":"2011-12-2T14:01:07+02:00",
"releaseTime":"2013-12-2T14:01:07+02:00",
"type":"Develop"
}
]
}
First Define Classes you will get everything
public class Version {
private List<Versions> versions;
public List<Versions> getVersions() {
return versions;
}
public void setVersions(List<Versions> versions) {
this.versions = versions;
}
#Override
public String toString() {
return "Version [versions=" + versions + "]";
}
}
public class Versions {
private String id;
private String time;
private String releaseTime;
private String type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getReleaseTime() {
return releaseTime;
}
public void setReleaseTime(String releaseTime) {
this.releaseTime = releaseTime;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#Override
public String toString() {
return "Versions [id=" + id + ", time=" + time + ", releaseTime="
+ releaseTime + ", type=" + type + "]";
}
}
Finally you can parse the JSON as like here
JsonReader reader = new JsonReader(new FileReader(Constants.VersJson));
Gson gson = new Gson();
Version version = gson.fromJson(reader, Version.class);

i have also faced json array parsing using gson here is my code solved it
this is my reader class functions
JsonReader reader = new JsonReader(new InputStreamReader(new FileInputStream(myFile)));
System.out.println( reader);
Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonArray jArray = parser.parse(reader).getAsJsonArray();
ArrayList<JsonOperations> lcs = new ArrayList<JsonOperations>();
for(JsonElement obj : jArray )
{
JsonOperations cse = gson.fromJson( obj , JsonOperations.class);
lcs.add(cse);
}
for ( JsonOperations tUser : lcs)
{
System.out.println(tUser);
}
my json operation class is
public class JsonOperations {
String match_id, pool_name, team1_name, team1_image, team2_name,
team2_image, match_date, match_country, match_venue, predicted;
public JsonOperations() {
}
public JsonOperations(String match_id, String pool_name, String team1_name,
String team1_image, String team2_name, String team2_image,
String match_date, String match_country, String match_venue,
String predicted) {
this.match_id = match_id;
this.pool_name = pool_name;
this.team1_name = team1_name;
this.team1_image = team1_image;
this.team2_name = team2_name;
this.team2_image = team2_image;
this.match_date = match_date;
this.match_country = match_country;
this.match_venue = match_venue;
this.predicted = predicted;
}
public void set_team1(String team1_name) {
this.team1_name = team1_name;
}
public void set_team2(String team2_name) {
this.team2_name = team2_name;
}
public String get_team1() {
return team1_name;
}
public String get_team2() {
return team2_name;
}
#Override
public String toString() {
// TODO Auto-generated method stub
return this.get_team1() + this.get_team2();
}
}

Related

Converting a string to list of Objects in java

I have this string:
[{
"expectedInput": "hello",
"expectedResponse": "how can i help you?"
},
{
"expectedInput": "need sip support",
"expectedResponse": "ok, let me check "
}
]
and i want to convert into List of Objects i.e List<MessageDetails>
where MessageDetails.class is
public class MessageDetails {
private String expectedInput;
private String expectedResponse;
public String getExpectedInput() {
return expectedInput;
}
public void setExpectedInput(String expectedInput) {
this.expectedInput = expectedInput;
}
public String getExpectedResponse() {
return expectedResponse;
}
public void setExpectedResponse(String expectedResponse) {
this.expectedResponse = expectedResponse;
}
}
You can easily do it with the help of Jackson:
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(source);
List<MessageDetails> list = Arrays.asList(mapper.treeToValue(node, MessageDetails[].class));
for (MessageDetails messageDetail : list) {
System.out.println(messageDetail.getExpectedInput() + ": " + messageDetail.getExpectedResponse());
}

How to identify if data received from API is in Array Format or Object Format in JAVA?

This is my 1st java project.
I m using a 3rd party Flight API in Java.
Actually the issue is, if the data received only has 1 record, I get data in Object format and if data received has more than 1 record, I get data in Array format. Now the issue is, I created a POJO class in which I defined it as Array but when i get data in Object format, It gives error :
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1
public class MlFlightGetFlightAvailibilityResponse {
private MlAirlineList[] AirlineList;
public MlAirlineList[] getAirlineList() {
return AirlineList;
}
public void setAirlineList(MlAirlineList[] AirlineList) {
this.AirlineList = AirlineList;
}
#Override
public String toString() {
return "ClassPojo [AirlineList = " + AirlineList + "]";
}
}
public class MlAirlineList {
private String AirlineCode;
private String AirlineName;
public MlAirlineList(String AirlineCode, String AirlineName) {
this.AirlineCode = AirlineCode;
this.AirlineName = AirlineName;
}
public String getAirlineCode() {
return AirlineCode;
}
public void setAirlineCode(String AirlineCode) {
this.AirlineCode = AirlineCode;
}
public String getAirlineName() {
return AirlineName;
}
public void setAirlineName(String AirlineName) {
this.AirlineName = AirlineName;
}
#Override
public String toString() {
return "ClassPojo [AirlineCode = " + AirlineCode + ", AirlineName = " + AirlineName + "]";
}
}
Below is the for loop in which i get error
Map<String, String> mlFlightAirline = new HashMap<>(); // Unique Flight Airline List
Gson gson = new Gson();
MlFlightResponse mlflights = gson.fromJson(mlResponse, MlFlightResponse.class); // mlResponse is JSON response
public class MlFlightResponse {
private MlFlightGetFlightAvailibilityResponse GetFlightAvailibilityResponse;
public MlFlightGetFlightAvailibilityResponse getGetFlightAvailibilityResponse() {
return GetFlightAvailibilityResponse;
}
public void setGetFlightAvailibilityResponse(MlFlightGetFlightAvailibilityResponse GetFlightAvailibilityResponse) {
this.GetFlightAvailibilityResponse = GetFlightAvailibilityResponse;
}
#Override
public String toString() {
return "ClassPojo [GetFlightAvailibilityResponse = " + GetFlightAvailibilityResponse + "]";
}
}
for (MlAirlineList airline : mlflights.getGetFlightAvailibilityResponse().getAirlineList()) {
mlFlightAirline.put(airline.getAirlineCode(), airline.getAirlineName());
}
In Above code, MlAirlineList sometimes comes as Array and sometimes has Object based on number of records available.
Object Data Format:
{
"AirlineList": {
"AirlineCode":"test",
"AirlineName":"test"
}
}
{
"AirlineList": [{
"AirlineCode":"test",
"AirlineName":"test"
},
{
"AirlineCode":"test",
"AirlineName":"test"
}]
}
Please guide me in right direction.
Thanks
From what I can see you have an Array of Arrays in JSON response you are trying to process.
Try
for (MlAirlineList airline : mlflights.getGetFlightAvailibilityResponse().getAirlineList()) {
mlFlightAirline.put(airline[0], airline[1]);
}
You can put manual check for this for hot-fix.If response start with "{" and ends with "}" then you can add [ and ] into the response in start and end part .this will surely work

Get api param from json file java with arrays

I have a json a file that doesnt contain only my api i am new to json and trying to get my api parameters from the file
"operators": {
"tez" : {
"api": "www.my-tour.com/search/getResult",
"parameters": [
{
"country": "Canada",
"queryParameters": {
"priceMin": ["0"],
"priceMax":["150000"],
"currency":["5561"],
"nightsMin":[1,2,3,4,5,6,7,8,9,10,11,12,13],
"nightsMax":[1,2,3,4,5,6,7,8,9,10,11,12,13]
In my app operator is just simple the company that owns the api so i have many operators so "tez" is the name of the company and below is its api and param
#Override
public JsonObject fetchData(String url) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DAY_OF_MONTH, 20);
for (int i = 1; i <= 180; i++) {
String formattedDate = dateFormat.format(calendar);
url += "&after=" + formattedDate + "&before=" + formattedDate;
// how can i get the api iteratively to get all api param
JsonObject json = new JsonObject().getJsonObject("tez");
// TODO call eternal API here
JSONParser parser = new JSONParser();
JsonObject a = null;
try {
FileReader fileReader = new FileReader("\\home\\user\\MyProjects\\MicroserviceBoilerPlate\\src\\config\\local_file.json");
a = (JsonObject) parser.parse(fileReader);
} catch (Exception e1) {
e1.printStackTrace();
}
This above is what i am came up with but its not correct im not able to access the json file and how can i iterate through the parameters so i can add them to the api
www.my-tour.com/search/getResult?priceMin=0&priceMax=150000&currency=+value &nightsMin= + value &nightsMax=+values etc
Note: This is a vertx app and i am using JsonObject and other Json specific api's
You could just make an object of the JSON properties in the file
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;
#JsonIgnoreProperties(ignoreUnknown = true)
public class TezModel {
public Operators operators;
public String getApi() {
return operators.tez.api;
}
public List<String> getPriceMin() {
return operators.tez.parameters.get(0).queryParameters.priceMin;
}
public List<String> getPriceMax() {
return operators.tez.parameters.get(0).queryParameters.priceMax;
}
public List<String> getCurrency() {
return operators.tez.parameters.get(0).queryParameters.currency;
}
public List<Integer> getNightsMin() {
return operators.tez.parameters.get(0).queryParameters.nightsMin;
}
public List<Integer> getNightsMax() {
return operators.tez.parameters.get(0).queryParameters.nightsMax;
}
#JsonIgnoreProperties(ignoreUnknown = true)
public static class Operators {
public Tez tez;
}
#JsonIgnoreProperties(ignoreUnknown = true)
public static class Tez {
public String api;
public List<Parameters> parameters;
}
#JsonIgnoreProperties(ignoreUnknown = true)
public static class Parameters {
public String country;
public QueryParameters queryParameters;
}
#JsonIgnoreProperties(ignoreUnknown = true)
public static class QueryParameters {
public List<String> priceMin;
public List<String> priceMax;
public List<String> currency;
public List<Integer> nightsMin;
public List<Integer> nightsMax;
}
}
And then you could add your parameters to a string using jackson databind
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
TezModel tezModel = mapper.readValue(new File("local_file.json"), TezModel.class);
String api = tezModel.getApi()+ "+priceMin="
+ tezModel.getPriceMin().get(0)
+ "&priceMax=" + tezModel.getPriceMax().get(0)
+ "&currency=+" + tezModel.getCurrency().get(0)
+ "nightsMin=" + tezModel.getNightsMin().get(0)
+ "nightsMax=" + tezModel.getNightsMax().get(0);
System.out.println(api);
}

Build dynamic JSON

I'm trying to build dynamic json request in java to send to my c++ server. I'm using the GSON library.
This is my json example:
{
"nodes": {
"12131231231231241": {
"gToken": {
"token": "AABBCCDDEEFF99001122334455667788"
},
"objects": {
"WATER_CONTROL_1": "0"
}
},
"7682642342432423": {
"userAuthentication": {
"userEmail": "user#mail.com",
"userPassword": "userPassword"
},
"objects": {
"LIGHT_1_CONTROL": "1"
}
}
}
}
If you can see the nodes object is dynamic. Inside him i can have a lot of items (in the example i put two, representing by 12131231231231241 and 7682642342432423). Inside each item the authentication method can be different (by token, by email/password) and inside objects item i can have a lot of different dynamic items too.
The part to send to my c++ server, parse the JSON and do the all validations (authetication for example) is already done and working (i test this json example inside c++ string, encode to json and do the parse, get the all items,etc).
So my problem is to build my class to send the request with some struct to corresponding to this dynamic json.
I already implement some other class to send json to my server and its work because i already know the json expected and on other cases the json have a static/fixed content.
My class for this dynamic json:
public class MonitorControlGetRequestArgs implements SerializableJSON {
Nodes nodes;
public MonitorControlGetRequestArgs() {
nodes = new Nodes();
}
static class Nodes{
public Nodes(){
}
}
public static MonitorControlGetRequestArgs fromStringJson(String data){
try {
Gson gson = new Gson();
return gson.fromJson(data, MonitorControlGetRequestArgs.class);
}
catch(Exception e){
return null;
}
}
public static MonitorControlGetRequestArgs fromBytesJson(byte[] data){
if (data == null)
return null;
try {
String str = new String(data, "utf-8");
return fromStringJson(str);
}
catch (Exception e) {
return null;
}
}
#Override
public String toJsonString(){
try{
Gson gson = new Gson();
return gson.toJson(this);
}
catch(Exception e){
return null;
}
}
#Override
public byte[] toJsonBytes(){
try {
return this.toJsonString().getBytes("utf-8");
}
catch (Exception e){
return null;
}
}
}
I create a static class Nodes empty to show you. In my server c++ i receive the item nodes in json format, but now i have a lot of doubts how to build the struct inside nodes to corresponding to my dynamic json.
I hope you understand my doubts. If you don't understand something tell to me.
EDIT 1 - (try to use the example of Andriy Rymar)
I try to simulate this json:
{
"nodes": {
"1317055040393017962": {
"userAuthentication": {
"userEmail": "rr#rr.com",
"userPassword": "rr123"
}
}
}
}
My request class:
public class MonitorControlGetRequestArgs implements SerializableJSON
{
private final static String nodeTemplate = "\"%s\":%s";
List nodes = new ArrayList<>();
public MonitorControlGetRequestArgs(UserAuthentication userAuthentication)
{
JsonData jsonData = new JsonData();
jsonData.addNode(new Node("1317055040393017962", new NodeObject(userAuthentication)));
}
static class Node
{
private final String nodeName;
private final Object nodeBody;
public Node(String nodeName, Object nodeBody) {
this.nodeName = nodeName;
this.nodeBody = nodeBody;
}
public String getNodeName() {
return nodeName;
}
public Object getNodeBody() {
return nodeBody;
}
}
static class JsonData {
List<Node> nodes = new ArrayList<>();
public void addNode(Node node){
nodes.add(node);
}
}
static class NodeObject
{
UserAuthentication userAuthentication;
public NodeObject(UserAuthentication userAuthentication)
{
this.userAuthentication = userAuthentication;
}
}
public static MonitorControlGetRequestArgs fromStringJson(String data)
{
try
{
Gson gson = new Gson();
return gson.fromJson(data, MonitorControlGetRequestArgs.class);
}
catch(Exception e)
{
return null;
}
}
public static MonitorControlGetRequestArgs fromBytesJson(byte[] data)
{
if (data == null) return null;
try
{
String str = new String(data, "utf-8");
return fromStringJson(str);
}
catch (Exception e)
{
return null;
}
}
#Override
public String toJsonString()
{
try
{
Gson gson = new Gson();
return gson.toJson(this);
}
catch(Exception e)
{
return null;
}
}
#Override
public byte[] toJsonBytes()
{
try
{
return this.toJsonString().getBytes("utf-8");
}
catch (Exception e)
{
return null;
}
}
}
EDIT 2
I will try to explain better,i believe I was not totally explicit. My application java is a REST application that send json to my c++ server. In my server i receive the json, i do the parse, i do the validation, the operations, etc and return back to my java client the response in json too.
For example, imagine that my json request body (to create a new user for example) is something like this:
{
"userInformation": {
"name": "user name",
"age": 33
}
}
For this i don't have any doubts how to do (i already implement a lot of requests very similar). I can create a static class like this:
static class UserInfo
{
String name;
String age;
public UserInfo(String name, String age)
{
this.name = name;
this.age = age;
}
}
And inside a request class (very similar to a class like i copy before - MonitorControlGetRequestArgs) i create a new instance to my UserInfo
UserInfo userInformation = new UserInfo (name, age)
In this case its easy because the request json body is static. I already now that i have a userInformation section and inside i have a name and age. To create a list with userInfo (to create multiple users at same time for example) i already implement things like this.
But now, for this specific case i have this json:
{
"nodes": {
"12131231231231241": {
"gToken": {
"token": "AABBCCDDEEFF99001122334455667788"
},
"objects": {
"WATER_CONTROL_1": "0"
}
},
"7682642342432423": {
"userAuthentication": {
"userEmail": "user#mail.com",
"userPassword": "userPassword"
},
"objects": {
"LIGHT_1_CONTROL": "1"
"LIGHT_3_CONTROL": "0"
}
}
}
}
So in this case i have some problems. In these example i put two items (12131231231231241,7682642342432423) but the user can send more (3,4,5,50,100). In the other hand inside nodes i have two sections (12131231231231241,7682642342432423) but this numbers are some ids that i use in my app and i never know that ids the user will put. In last example ( userInformation ) its simple because i create a userInformation section because i already know that the user always put this section, it is static. In these new json request i dont know, because i never now what value he put, i only know that is a string. The authentication method i dont have problems to create. But other problem that i expected to have is in objects section, because the user can put to a lot of objects and i never know what is the key (in userInformation i know that the keys are always the name and age for example and only exits these two keys, i these new case i dont know what is the keys and what are the number of pair of keys/values he put).
EDIT 3 -
I implement this code and i could almost produce all the structure I need. I'm using the gson same.
Nodes nodes;
public MonitorControlGetRequestArgs(String userEmail, String userPassword, Map <String,String> objects)
{
nodes = new Nodes(userEmail, userPassword, objects);
}
static class Nodes
{
AuthenticationMethod authenticationMethod;
Map <String,String> objects;
public Nodes(String userEmail, String userPassword, Map <String,String> objects)
{
authenticationMethod = new AuthenticationMethod(userEmail, userPassword);
this.objects = objects;
}
}
The result json:
{
"nodes": {
"authenticationMethod": {
"userAuthentication": {
"userEmail": "user#mail.com",
"userPassword": "userPassword"
}
},
"objects": {
"aa": "aaaaaaaaaaaaa",
"bbbbbbb": "bbbbb",
"ccdd": "ccddccdd"
}
}
}
Know i only need to add some struct to support this json:
{
"nodes": {
"7682642342432423": {
"authenticationMethod": {
"userAuthentication": {
"userEmail": "user#mail.com",
"userPassword": "userPassword"
}
},
"objects": {
"0": "Hammersmith & City",
"1": "Circle",
"dasd": "dasda"
}
}
}
}
Note: The objects is a map, so i can put the number of objects string/string that i want. Know i need to do something to support the previous json with the 7682642342432423, 12131231231231241, etc, etc..
EDIT 4 - final
Map <String, Obj> nodes;
public MonitorControlGetRequestArgs(Map <String, Obj> nodes)
{
this.nodes = nodes;
}
static class Obj
{
AuthenticationMethod authenticationMethod;
Map <String,String> objects;
public Obj(String userEmail, String userPassword, Map <String,String> objects)
{
authenticationMethod = new AuthenticationMethod(userEmail, userPassword);
this.objects = objects;
}
}
Json that arrive in my server (like i want)
{
"nodes": {
"12131231231231241": {
"authenticationMethod": {
"userAuthentication": {
"userEmail": "user#mail.com",
"userPassword": "userPassword"
}
},
"objects": {
"aa": "aaaaaaaaaaaaa",
"bbbbbbb": "bbbbb",
"ccdd": "ccddccdd"
}
},
"777777777777777": {
"authenticationMethod": {
"userAuthentication": {
"userEmail": "user#mail.com",
"userPassword": "userPassword"
}
},
"objects": {
"aa": "aaaaaaaaaaaaa",
"bbbbbbb": "bbbbb",
"ccdd": "ccddccdd"
}
}
}
}
Here is improved code from previous example that is more flexible and has better serialization mechanism :
public class ForTestApplication {
public static void main(String[] args) {
NodeArray jsonContainer = new NodeArray(
new Node("nodes", new NodeArray(
new Node("12131231231231241", new NodeArray(
new Node("gToken",
new Node("token", "AABBCCDDEEFF99001122334455667788")),
new Node("objects", new NodeArray(
new Node("WATER_CONTROL_1", "0"),
new Node("WATER_CONTROL_2", "1")
)))),
new Node("7682642342432423", new NodeArray(
new Node("userAuthentication", new NodeArray(
new Node("userEmail","user#mail.com"),
new Node("userPassword","userPassword")
)),
new Node("objects", new NodeArray(
new Node("WATER_CONTROL_1", "0"),
new Node("WATER_CONTROL_2", "1")
))
))
)));
System.out.println(jsonContainer.toJSONString());
}
}
class NodeArray {
private static final String NODE_TEMPLATE = "\"%s\":%s";
private static final Gson gson = new Gson();
private List<Node> nodes = new ArrayList<>();
public NodeArray(Node... nodes){
addNode(nodes);
}
public void addNode(Node... node){
nodes.addAll(Arrays.asList(node));
}
public String toJSONString() {
return nodes.stream()
.map(node -> String.format(NODE_TEMPLATE, node.getNodeName(), getNodeBodyAsJSON(node)))
.collect(Collectors.joining(",", "{", "}"));
}
private String getNodeBodyAsJSON(Node node) {
if (node.getNodeBody() instanceof NodeArray) {
return ((NodeArray) node.getNodeBody()).toJSONString();
}
return gson.toJson(node.getNodeBody());
}
}
class Node {
private final String nodeName;
private final Object nodeBody;
public Node(String nodeName, Object nodeBody) {
this.nodeName = nodeName;
this.nodeBody = nodeBody;
}
public String getNodeName() {
return nodeName;
}
public Object getNodeBody() {
return nodeBody;
}
}
The output of such application is :
{"nodes":{"12131231231231241":{"gToken":{"nodeName":"token","nodeBody":"AABBCCDDEEFF99001122334455667788"},"objects":{"WATER_CONTROL_1":"0","WATER_CONTROL_2":"1"}},"7682642342432423":{"userAuthentication":{"userEmail":"user#mail.com","userPassword":"userPassword"},"objects":{"WATER_CONTROL_1":"0","WATER_CONTROL_2":"1"}}}}
Pretty view is :
NOTICE : this example use constructors to build complex structures but I highly recommend to use builder pattern for such case. Code will be clearer and better.
Here is example of what you need using Gson. But if you would like to use something else, for example OrgJson then the code will be more clear and without String templates.
public class ForTestApplication {
private final static String nodeTemplate = "\"%s\":%s";
public static void main(String[] args) {
JsonData jsonData = new JsonData();
jsonData.addNode(new Node("user-1", new TestObject(62, "James", "Gosling")));
jsonData.addNode(new Node("user-2", new TestObject(53, "James", "Hetfield")));
System.out.println(jsonData.toJSONStirng());
}
static class JsonData {
List<Node> nodes = new ArrayList<>();
public void addNode(Node node){
nodes.add(node);
}
public String toJSONStirng() {
Gson gson = new Gson();
return nodes.stream()
.map(node -> String.format(nodeTemplate, node.getNodeName(), gson.toJson(node.getNodeBody())))
.collect(Collectors.joining(",", "{", "}"));
}
}
static class Node {
private final String nodeName;
private final Object nodeBody;
public Node(String nodeName, Object nodeBody) {
this.nodeName = nodeName;
this.nodeBody = nodeBody;
}
public String getNodeName() {
return nodeName;
}
public Object getNodeBody() {
return nodeBody;
}
}
static class TestObject {
private int age;
private String firstName;
private String lastName;
public TestObject(int age, String firstName, String lastName) {
this.age = age;
this.firstName = firstName;
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
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;
}
}
}
Output :
{"user-1":{"age":62,"firstName":"James","lastName":"Gosling"},"user-2":{"age":53,"firstName":"James","lastName":"Hetfield"}}
Pretty view :

How to serialize json to another json by preserving data types of key?

I have my original JSON String like this in which I have key and value as shown below -
{
"u":{
"string":"1235"
},
"p":"2047935",
"client_id":{
"string":"5"
},
"origin":null,
"item_condition":null,
"country_id":{
"int":3
},
"timestamp":{
"long":1417823759555
},
"impression_id":{
"string":"2345HH*"
},
"is_consumerid":true,
"is_pid":false
}
As an example, one key is "u" and its value is -
{
"string":"1235"
}
Similarly another key is "country_id" and its value is -
{
"int":3
}
Now what I need to do is, I need to represent key value pair as shown below. If any value is string data type (like value for key u), then represent it's value in double quotes, otherwise don't represent it's value in double quotes. Meaning value of country_id won't be in String double quotes since it is an int.
"u": "1235"
"p": "2047935"
"client_id": "5"
"origin":null
"item_condition":null
"country_id": 3 // I don't have double quotes here around 3 since country_id was int that's why
"timestamp": 1417823759555
"impression_id": "2345HH*"
"is_consumerid": true
"is_pid": false
And then I need to make another json string which should look like this -
{
"u": "1235",
"p": "2047935",
"client_id": "5",
"origin":null,
"item_condition":null,
"country_id": 3,
"timestamp": 1417823759555,
"impression_id": "2345HH*",
"is_consumerid": true,
"is_pid": false
}
So I started with below code but not able to understand what should I do further?
String response = "original_json_string";
Type type = new TypeToken<Map<String, Object>>() {}.getType();
JsonObject jsonObject = new JsonParser().parse(response).getAsJsonObject();
for (Map.Entry<String, JsonElement> object : jsonObject.entrySet()) {
if (object.getValue() instanceof JsonObject) {
String data = object.getValue().toString();
// now not sure what should I do here?
}
}
And my new json should print out like this after serializing.
{
"u": "1235",
"p": "2047935",
"client_id": "5",
"origin":null,
"item_condition":null,
"country_id": 3,
"timestamp": 1417823759555,
"impression_id": "2345HH*",
"is_consumerid": true,
"is_pid": false
}
What is the best way to achieve this?
Note that I'm not yet very experienced with Gson, so there might be easiest ways to do it. Also this solution comes up after the discussion we had previously.
Basically the problem was to get the wanted type in the json file back (which is done by the addEntry method) and each #event key should have its own JSON string (done by computeJson). Since there are only two nested levels, it's fine to do it like that. Otherwise a recursive approach will do the trick.
So if you have only one nested level, you should iterate other the JsonObject's entries'. For each entries, computeJson will add a new Json entry in the List which corresponds to each #event key.
public class Test {
public static void main(String[] args) throws Exception {
List<String> output = new ArrayList<>();
JsonObject jsonObject = new JsonParser().parse(new FileReader("myJson.json")).getAsJsonObject();
for (Map.Entry<String, JsonElement> object : jsonObject.entrySet()) {
if (object.getValue() instanceof JsonObject) {
output.add(computeJson((JsonObject)object.getValue()));
}
}
System.out.println(output);
}
private static String computeJson(JsonObject source) {
JsonObject output = new JsonObject();
for (Map.Entry<String, JsonElement> object : source.entrySet()) {
if (object.getValue() instanceof JsonObject) {
for(Map.Entry<String, JsonElement> entry : ((JsonObject)object.getValue()).entrySet()) {
addEntry(object.getKey(), output, entry);
}
} else {
addEntry(object.getKey(), output, object);
}
}
Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
return gson.toJson(output);
}
private static void addEntry(String key, JsonObject output, Map.Entry<String, JsonElement> object) {
switch(object.getKey().toLowerCase()) {
case "string":
output.addProperty(key, object.getValue().getAsString());
break;
case "int":
output.addProperty(key, object.getValue().getAsInt());
break;
case "long":
output.addProperty(key, object.getValue().getAsLong());
break;
//add other primitive cases
default:
output.add(key, object.getValue());
}
}
}
As described here RawCollectionsExample you can manually parse the json and set it in the desired object. Once values are parsed and set you can again serialize the java object to have desired json.
For setting values from your json you need to have POJO shown below.
public class CustomObject {
private String u;
private String p;
private String client_id;
private String origin;
private String item_condition;
private int country_id;
private long timestamp;
private String impression_id;
private boolean is_consumerid;
private boolean is_pid;
public String getU() {
return u;
}
public void setU(String u) {
this.u = u;
}
public String getP() {
return p;
}
public void setP(String p) {
this.p = p;
}
public String getClient_id() {
return client_id;
}
public void setClient_id(String clientId) {
client_id = clientId;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getItem_condition() {
return item_condition;
}
public void setItem_condition(String itemCondition) {
item_condition = itemCondition;
}
public int getCountry_id() {
return country_id;
}
public void setCountry_id(int countryId) {
country_id = countryId;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getImpression_id() {
return impression_id;
}
public void setImpression_id(String impressionId) {
impression_id = impressionId;
}
public boolean isIs_consumerid() {
return is_consumerid;
}
public void setIs_consumerid(boolean isConsumerid) {
is_consumerid = isConsumerid;
}
public boolean isIs_pid() {
return is_pid;
}
public void setIs_pid(boolean isPid) {
is_pid = isPid;
}
#Override
public String toString() {
return "CustomObject [client_id=" + client_id + ", country_id="
+ country_id + ", impression_id=" + impression_id
+ ", is_consumerid=" + is_consumerid + ", is_pid=" + is_pid
+ ", item_condition=" + item_condition + ", origin=" + origin
+ ", p=" + p + ", timestamp=" + timestamp + ", u=" + u + "]";
}
}
In above POJO you can parse and set JSON value manually as shown below :
String jsonLine = "{ \"u\":{ \"string\":\"1235\" }, \"p\":\"2047935\", \"client_id\":{ \"string\":\"5\" }, \"origin\":null, \"item_condition\":null, \"country_id\":{ \"int\":3 }, \"timestamp\":{ \"long\":1417823759555 }, \"impression_id\":{ \"string\":\"2345HH*\" }, \"is_consumerid\":true, \"is_pid\":false}";
JsonParser parser = new JsonParser();
//in case you have json array you need to use .getAsJsonArray instead of getAsJsonObject
JsonObject jsonObject = parser.parse(jsonLine).getAsJsonObject();
CustomObject obj = new CustomObject();
obj.setP(jsonObject.get("p").getAsString());
obj.setU(jsonObject.get("u").getAsJsonObject().get("string").getAsString());
obj.setClient_id(jsonObject.get("client_id").getAsJsonObject().get("string").getAsString());
//null check which will be required for each value in case there are possibility of having null values
String origin = jsonObject.get("origin").isJsonNull() ==true?null:jsonObject.get("origin").getAsString();
obj.setOrigin(origin);
String itemCondition = jsonObject.get("item_condition").isJsonNull() ==true?null:jsonObject.get("item_condition").getAsString();
obj.setItem_condition(itemCondition);
obj.setCountry_id(jsonObject.get("country_id").getAsJsonObject().get("int").getAsInt());
obj.setTimestamp(jsonObject.get("timestamp").getAsJsonObject().get("long").getAsLong());
obj.setImpression_id(jsonObject.get("impression_id").getAsJsonObject().get("string").getAsString());
obj.setIs_consumerid(jsonObject.get("is_consumerid").getAsBoolean());
obj.setIs_pid(jsonObject.get("is_consumerid").getAsBoolean());
System.out.println("JSON OUTPUT "+ new Gson().toJson(obj));
You can run the code snippet in any class's main method to validate. Check the last line above which outputs required json. Let me know if this is not what you were looking for.

Categories

Resources