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());
}
Related
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
I have happily been using Google Gson to parse extract some JSON metadata of the form
{
"lowlevel": {
"average_loudness": 0.570070445538
},
"rhythm": {
"beats_count": 502,
"bpm": 128.347702026
},
"tonal": {
"chords_changes_rate": 0.0534749031067
"tuning_diatonic_strength": 0.431238204241,
"tuning_equal_tempered_deviation": 0.164615109563,
"tuning_frequency": 434.193115234,
"tuning_nontempered_energy_ratio": 0.847496032715
}
}
Using this
public class AcousticBrainzLowlevelWrapper
{
private AcousticBrainzLowLevelRhythm rhythm;
private AcousticBrainzLowLevelTonal tonal;
public AcousticBrainzLowLevelRhythm getRhythm()
{
return rhythm;
}
public void setRhythm(AcousticBrainzLowLevelRhythm rhythm)
{
this.rhythm = rhythm;
}
public AcousticBrainzLowLevelTonal getTonal()
{
return tonal;
}
public void setTonal(AcousticBrainzLowLevelTonal tonal)
{
this.tonal = tonal;
}
}
and
AcousticBrainzLowlevelWrapper low = gson.fromJson(result, AcousticBrainzLowlevelWrapper.class) ;
(Full JSON can be seen here)
but now the API has been extended to allow multiple lookups such as this url
which now returns
{
"96685213-a25c-4678-9a13-abd9ec81cf35": {
"0": {
"lowlevel": {
"average_loudness": 0.570070445538
},
"rhythm": {
"beats_count": 502,
"bpm": 128.347702026
},
"tonal": {
"chords_changes_rate": 0.0534749031067
"tuning_diatonic_strength": 0.431238204241,
"tuning_equal_tempered_deviation": 0.164615109563,
"tuning_frequency": 434.193115234,
"tuning_nontempered_energy_ratio": 0.847496032715
}
}
.....
"78787888-a25c-4678-9a13-abd9ec81cf35": {
"0": {
"lowlevel": {
......
..
The difference being that the json doesn't define what "96685213-a25c-4678-9a13-abd9ec81cf35" and "78787888-a25c-4678-9a13-abd9ec81cf35" are, or what "0" is.
So I know what they represent (MusicBrainzRecording and offset) but I cannot create a class like AcousticBrainzLowlevelWrapper to represent this, so how do I parse this new api.
Update
I tried creating
public class AcousticBrainzLowLevelList
{
private Map<String, AcousticBrainzLowlevelWrapper> data = new HashMap<>();
public Map<String, AcousticBrainzLowlevelWrapper> getData()
{
return data;
}
public void setData(Map<String, AcousticBrainzLowlevelWrapper> data)
{
this.data = data;
}
}
and then calling
AcousticBrainzLowLevelList lowMap = gson.fromJson(result, AcousticBrainzLowLevelList.class) ;
but nothing get added to the map. Unsuprisingly because data I dont' see how can i give a name since there is no consistent name at the top level.
It seems to me that your input JSON could be parsed to produce a Java class of type Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>> :
Type type = new TypeToken<Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>>>(){}.getType();
Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>> result = gson.fromJson(json, type);
As I wrote it, I might as well post it:
Similar to Maurice's answer
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Map;
public class Main {
private final static String jsonSingle =
"{ \"attribute1\": \"value1\", \"attribute2\": \"value2\" }";
private final static String jsonMultiple =
"{\n" +
" \"96685213-a25c-4678-9a13-abd9ec81cf35\": {\n" +
" \"0\": { \"attribute1\": \"value1\", \"attribute2\": \"value2\" }\n" +
" },\n" +
" \"78787888-a25c-4678-9a13-abd9ec81cf35\": {\n" +
" \"0\": { \"attribute1\": \"value3\", \"attribute2\": \"value4\" }\n" +
"}}";
public static void main(String[] args) {
MyBean bean = new Gson().fromJson(jsonSingle, MyBean.class);
System.out.println(bean);
Type type = new TypeToken<Map<String, Map<String, MyBean>>>(){}.getType();
Map<String, String> myMap = new Gson().fromJson(jsonMultiple, type);
System.out.println(myMap);
}
}
MyBean class:
class MyBean {
String attribute1;
String attribute2;
public String getAttribute1() {
return attribute1;
}
public void setAttribute1(String attribute1) {
this.attribute1 = attribute1;
}
public String getAttribute2() {
return attribute2;
}
public void setAttribute2(String attribute2) {
this.attribute2 = attribute2;
}
#Override
public String toString() {
return "MyBean: <attribute1: " + attribute1 + " | " + "attribute2: " + attribute2 + ">";
}
}
Outputs:
MyBean: <attribute1: value1 | attribute2: value2>
and
{96685213-a25c-4678-9a13-abd9ec81cf35={0=MyBean: <attribute1: value1 | attribute2: value2>}, 78787888-a25c-4678-9a13-abd9ec81cf35={0=MyBean: <attribute1: value3 | attribute2: value4>}}
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.
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();
}
}
I have a JsonNode which contains the following JSON. Inside that JsonNode object is an array. In that array there are three fields, one of which, slaid, is a list. The other two are strings. Here is the JSON.
{
"SLA": [
{
"slaid": [
"53637cc144ae8b607e089701"
],
"ragindicator": "Red",
"name": "r1"
},
{
"slaid": [
"53637d1844ae8b607e089704"
],
"ragindicator": "Amber",
"name": "a1"
},
{
"slaid": [
"53637eac44ae8b607e089706"
],
"ragindicator": "Green",
"name": "g1"
}
]
}
I want to parse this value. How can I parse it , where slaid's type is List<String>? I have tried some ways but I am still unable to find the solution.
The easiest way I can see is creating POJO classes which fit to your JSON:
class Slaids {
#JsonProperty("SLA")
private List<Slaid> slaids;
public List<Slaid> getSlaids() {
return slaids;
}
public void setSlaids(List<Slaid> slaids) {
this.slaids = slaids;
}
#Override
public String toString() {
return slaids.toString();
}
}
class Slaid {
private List<String> slaid;
private String ragindicator;
private String name;
public List<String> getSlaid() {
return slaid;
}
public void setSlaid(List<String> slaid) {
this.slaid = slaid;
}
public String getRagindicator() {
return ragindicator;
}
public void setRagindicator(String ragindicator) {
this.ragindicator = ragindicator;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Slaid [slaid=" + slaid + ", ragindicator=" + ragindicator + ", name=" + name + "]";
}
}
Simple usage:
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(json, Slaids.class));
Above program prints:
[Slaid [slaid=[53637cc144ae8b607e089701], ragindicator=Red, name=r1], Slaid [slaid=[53637d1844ae8b607e089704], ragindicator=Amber, name=a1], Slaid [slaid=[53637eac44ae8b607e089706], ragindicator=Green, name=g1]]
If you want to use JsonNode you can do it in this way:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(json);
ArrayNode slaidsNode = (ArrayNode) rootNode.get("SLA");
Iterator<JsonNode> slaidsIterator = slaidsNode.elements();
while (slaidsIterator.hasNext()) {
JsonNode slaidNode = slaidsIterator.next();
System.out.println(slaidNode.get("slaid"));
System.out.println(slaidNode.get("ragindicator"));
System.out.println(slaidNode.get("name"));
}
Above program prints:
["53637cc144ae8b607e089701"]
"Red"
"r1"
["53637d1844ae8b607e089704"]
"Amber"
"a1"
["53637eac44ae8b607e089706"]
"Green"
"g1"