I am getting this data from server how to parse this data in java .
LabelField jsonResult = new LabelField(connectJson.response);
"[{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"}]"
I am getting response in jsonResult variable
You can use libraries like Jackson to do the same. There is also Google's GSON which will help you do the same. See this example
Take a look at the JSONParser Object in this Tutorial
If you are using Eclipse plugin than may JSON library included in you SDK.
Use below code to parse your JSON string got from the server.
String test = "[{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"},{\"screen_refresh_interval\":4,\"station_list_last_update\":\"update4\"}]";
JSONArray array = new JSONArray(test);
JSONObject obj = (JSONObject) array.get(0);
Your String look like you got JSON Array from the server.
First convert your Json string to JSON Array by
JSONArray array = new JSONArray(Your JSON String);
Each element in array represent JSON Object.You can read JSON Object by
JSONObject obj = (JSONObject) array.get(Index);
You can read parameter from Object to any String variable by :
String valueStr = obj.getString("screen_refresh_interval");
May this help you.
Design a class (viz CustomClass) first with screen_refresh_interval and station_list_last_update as properties. And Make a collection class for CustomClass
I'm using Gson as deserializer. Other libraries are also available.
public class Container {
private CustomClass[] classes;
public CustomClass[] getClasses() {
return classes;
}
public void setClasses(CustomClass[] classes) {
this.classes = classes;
}
}
public class CustomClass {
private String screen_refresh_interval;
private String station_list_last_update;
public String getScreen_refresh_interval() {
return screen_refresh_interval;
}
public void setScreen_refresh_interval(String screen_refresh_interval) {
this.screen_refresh_interval = screen_refresh_interval;
}
public String getStation_list_last_update() {
return station_list_last_update;
}
public void setStation_list_last_update(String station_list_last_update) {
this.station_list_last_update = station_list_last_update;
}
}
Gson gson = new Gson();
Container customClassCollection = gson.fromJson(jsonResult, Container.class);
Related
I have the following Java class
public static class LogItem {
public Long timestamp;
public Integer level;
public String topic;
public String type;
public String message;
}
and I want to convert an ArrayList<LogItem> into the following JSON string:
{"logitems":[
{"timestamp":1560924642000, "level":20, "topic":"websocket", "type":"status", "message":"connected (mobile)"},
...
]}`
I would like to do the following:
JSONArray logitems = new JSONArray();
for (DB_LogUtils.LogItem item : items) {
logitems.put(DB_LogUtils.asJSONObject(item)); // <----
}
JSONObject data = new JSONObject();
data.put("logitems", logitems);
webViewFragment.onInjectMessage(data.toString(), null);
where DB_LogUtils.asJSONObject is the following method
public static JSONObject asJSONObject(LogItem item) throws JSONException
{
JSONObject logitem = new JSONObject();
logitem.put("timestamp", item.timestamp);
logitem.put("level", item.level);
logitem.put("topic", item.topic);
logitem.put("type", item.type);
logitem.put("message", item.message);
return logitem;
}
but instead of doing this manually (like logitem.put("timestamp", item.timestamp);) I want to do this with Gson, so that I would end up with something like this
JSONArray logitems = new JSONArray();
for (DB_LogUtils.LogItem item : items) {
logitems.put(new Gson().toJSONObject(item)); // <----
}
JSONObject data = new JSONObject();
data.put("logitems", logitems);
webViewFragment.onInjectMessage(data.toString(), null);
in order to not have to edit the code at multiple points when the LogItem class changes.
But Gson().toJSONObject(...) does not exist, only Gson().toJson(...), which returns a String. I don't want to transition into a String only to then parse it with org.json.JSONObject.
I ended up using a second class
public static class LogItems {
public List<LogItem> logitems = new ArrayList<>();
}
which then let me change the whole code to
webViewFragment.onInjectMessage(new Gson().toJson(items), null);
where items would be of type LogItems.
In this case, creating the extra wrapper class was an overall benefit, but I'd still want to know how I can create such a JSONObject from a class by using Gson.
As far as i know it could be not possible without using for loop to iterate json string into array and store into map with same key.
But you can achieve your solution instead of passing dto pass the list of items into gson object as follow.
List<Object> list = new ArrayList<Object>();
list.add("1560924642000");
list.add(20);
list.add("websocket");
list.add("status");
list.add("connected (mobile)");
Gson gson = new Gson();
Map mp = new HashMap();
mp.put("ietams", list);
String json = gson.toJson(mp);
System.out.println(json);
output will be
{"logitems":["1560924642000",20,"websocket","status","connected (mobile)"]}
Hope this will help !
I have a class which holds other objects in an ArrayList:
class Program {
#Expose
private List<BaseData> dataList;
}
And I have other classes:
class BaseData {
#Expose
String name;
}
class Data extends BaseData {
#Expose
String description;
}
class DataA extends Data{
#Expose
String a;
}
class DataB extends Data{
#Expose
String b;
}
When I would like to serialize it:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Log.d(TAG, gson.toJson(myProgram));
I can see only the keys which I have in BaseData. My list in my Program object contains DataA, DataB and Data objects too.
How can I fix this?
Update:
So my program work like this: it does stuff and fills the Program's list with data. Than I save it: I use Gson to turn the Program to a json string. I use Shared Preferences.
Than when I open up the app again, it loads the previously saved json string. I Log.d it, and everything is cool.
Than
I would like to create a Program object from that json.
Gson gson = new Gson();
instance = gson.fromJson(savedJson, Program.class);
And after I serialize it again with Gson happens what I wrote above. So it seems that it only creates BaseData objects from the json.
I found the Solution.
Btw. It feels like a bit "brute force" method.
Gson gson = new Gson();
JSONObject progJsonObj = new JSONObject(json);
progJsonObj.clearDataList();
JSONArray dataList= reader.getJSONArray("dataList");
Program program = gson.fromJson(progJsonObj.toString());
for (int i = 0; i < dataList.length(); i++) {
JSONObject blockData = blocksInProgram.getJSONObject(i);
// Added new class variable of the base class
String type = blockData.getString("dataType");
if (type.equals("data_a")) {
DataA d = gson.fromJson(blockData.toString(), DataA.class);
program.addData(d);
} else if (type.equals("data_b")){
DataB d = gson.fromJson(blockData.toString(), DataB.class);
program.addData(d);
}
}
I have two JSON objects with similar fields. The only difference is that the first one always has field
type: "type1"
And second can have anything in 'type' field except 'type1'.
I want them to be parsed into java objects with different classes (using classes FirstType.class and OtherType.class). Is it possible?
Object one:
{
id: "1j23jr8swgs8"
type: "type1"
}
Object two:
{
id: "3sdaa3dq18"
type: "unknown_type"
}
And java classes:
class FirstType
{
String id;
}
class OtherType
{
String id;
}
Google gson will work nicely here.
You can do something like this:-
class ObjectName {
String id;
String type;
}
Gson gson = new GsonBuilder().serializeNulls().create();
ObjectName name = gson.fromJson(json, ObjectName.class);
FirstType firstType = null;
SecondType secondType = null;
if(name.type.equals("type1"))
firstType = new FirstType(name.id);
else
secondType = new SecondType(name.id);
It's been a heck of a long time since I used Gson, but it should look something like this:
//convert your json string into a json object
JsonElement element = new JsonParser().parse(jsonString);
JsonObject object = element.getAsJsonObject();
//get the relevant value from your object
String result = object.get("type").toString();
//compare and convert accordingly
if (result.equals("type1")) {
ObjectOne object = gson.fromJson(element, ObjectOne.class);
} else {
ObjectTwo object = gson.fromJson(element, ObjectTwo.class);
}
Try this and see if it works!
I want to send the server an http request with this json (upper line)
and I want to get such a json and parse it to Java object (lower line)
I remember from last times, that a missing field in a collection that I want to deserialize
crashes the deserialization
(for a single deserialization, if the json has no such field - a default value is inserted)
Is there any way I can create a single Java class to represent both the request json and the two types on response json objects?
My try:
public class ConfigValue {
public String key;
public String defaultValue;
public String value;
}
Gson gson = new Gson();
Type collectionType = new TypeToken<Array<ConfigValue>>() {
}.getType();
ConfigValue[] configValues = (ConfigValue[]) gson
.fromJson(result, collectionType);
Neither of the two JSON strings in your image are directly a list (or array) of ConfigValue objects. They are in fact a JSON object, with one property configValues, which is a list of ConfigValue objects. You therefore need a wrapper class to deserialize them to:
public class ConfigValues {
public ConfigValue[] configValues;
}
public class ConfigValue {
public String key;
public String defaultValue;
public String value;
}
public static void main(String[] args) {
String firstJson = "{\"configValues\":[{\"key\":\"radiusMeters\",\"value\":\"200\"}]}";
String secondJson = "{\"configValues\":[{\"key\":\"redeemExpirationMins\",\"defaultValue\":\"300\"},{\"key\":\"radiusMeters\",\"value\":\"200\",\"defaultValue\":\"400\"}]}";
Gson gson = new Gson();
ConfigValues firstConfigValues = gson.fromJson(firstJson, ConfigValues.class);
ConfigValues secondConfigValues = gson.fromJson(secondJson, ConfigValues.class);
System.out.println(firstConfigValues);
System.out.println(secondConfigValues);
}
If you add toString methods to the two classes, the main method prints the following deserialized objects:
ConfigValues(configValues=[ConfigValue(key=radiusMeters, defaultValue=null, value=200)])
ConfigValues(configValues=[ConfigValue(key=redeemExpirationMins, defaultValue=300, value=null), ConfigValue(key=radiusMeters, defaultValue=400, value=200)])
You can see that any missing fields of ConfigValue are deserialized to null.
Seems like Gson.toJson(Object object) generates JSON code with randomly spread fields of the object. Is there way to fix fields order somehow?
public class Foo {
public String bar;
public String baz;
public Foo( String bar, String baz ) {
this.bar = bar;
this.baz = baz;
}
}
Gson gson = new Gson();
String jsonRequest = gson.toJson(new Foo("bar","baz"));
The string jsonRequest can be:
{ "bar":"bar", "baz":"baz" } (correct)
{ "baz":"baz", "bar":"bar" } (wrong sequence)
You'd need to create a custom JSON serializer.
E.g.
public class FooJsonSerializer implements JsonSerializer<Foo> {
#Override
public JsonElement serialize(Foo foo, Type type, JsonSerializationContext context) {
JsonObject object = new JsonObject();
object.add("bar", context.serialize(foo.getBar());
object.add("baz", context.serialize(foo.getBaz());
// ...
return object;
}
}
and use it as follows:
Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class, new FooJsonSerializer()).create();
String json = gson.toJson(foo);
// ...
This maintains the order as you've specified in the serializer.
See also:
Gson User Guide - Custom serializers and deserializers
If GSON doesn't support definition of field order, there are other libraries that do. Jackson allows definining this with #JsonPropertyOrder, for example. Having to specify one's own custom serializer seems like awful lot of work to me.
And yes, I agree in that as per JSON specification, application should not expect specific ordering of fields.
Actually Gson.toJson(Object object) doesn't generate fields in random order. The order of resulted json depends on literal sequence of the fields' names.
I had the same problem and it was solved by literal order of properties' names in the class.
The example in the question will always return the following jsonRequest:
{ "bar":"bar", "baz":"baz" }
In order to have a specific order you should modify fields' names, ex: if you want baz to be first in order then comes bar:
public class Foo {
public String f1_baz;
public String f2_bar;
public Foo ( String f1_baz, String f2_bar ) {
this.f1_baz = f1_baz;
this.f2_bar = f2_bar;
}
}
jsonRequest will be { "f1_baz ":"baz", "f2_bar":"bar" }
Here's my solution for looping over json text files in a given directory and writing over the top of them with sorted versions:
private void standardizeFormat(File dir) throws IOException {
File[] directoryListing = dir.listFiles();
if (directoryListing != null) {
for (File child : directoryListing) {
String path = child.getPath();
JsonReader jsonReader = new JsonReader(new FileReader(path));
Gson gson = new GsonBuilder().setPrettyPrinting().registerTypeAdapter(LinkedTreeMap.class, new SortedJsonSerializer()).create();
Object data = gson.fromJson(jsonReader, Object.class);
JsonWriter jsonWriter = new JsonWriter(new FileWriter(path));
jsonWriter.setIndent(" ");
gson.toJson(data, Object.class, jsonWriter);
jsonWriter.close();
}
}
}
private class SortedJsonSerializer implements JsonSerializer<LinkedTreeMap> {
#Override
public JsonElement serialize(LinkedTreeMap foo, Type type, JsonSerializationContext context) {
JsonObject object = new JsonObject();
TreeSet sorted = Sets.newTreeSet(foo.keySet());
for (Object key : sorted) {
object.add((String) key, context.serialize(foo.get(key)));
}
return object;
}
}
It's pretty hacky because it depends on the fact that Gson uses LinkedTreeMap when the Type is simply Object. This is an implementation details that is probably not guaranteed. Anyway, it's good enough for my short-lived purposes...