convert JSON format to Java format - java

Need to achieve this JSON format of output as below using JAVA
[['2008-09-30 4:00PM',4], ['2008-10-30 4:00PM',6.5], ['2008-11-30 4:00PM',5.7], ['2008-12-30 4:00PM',9], ['2009-01-30 4:00PM',8.2]]
Cant use a list as the internal elements belong to string and integers (generics doesnt allow that).
Tried JsonObject of Gson also, it creates a map rather than a List.
http://jsfiddle.net/6heredzz/3/
Please help

My Java's a little rusty, but something like:
List<List<Object>> mainList = new ArrayList<List<Object>>();
for (--each inner list entry--) {
List<Object> innerList = new ArrayList<Object>();
String dateString = SomeDateFormatter.formatDate(theDate, "yyyy-MM-dd h:mmA");
innerList.add(dateString);
BigDecimal theValue = new BigDecimal("4");
innerList.add(theValue);
mainList.add(innerList);
}
String jsonString = SomeJsonSerializer.serializeList(mainList);
I leave you to pick your favorite date formatter, and your favorite JSON kit.

Related

Convert jsonobject to string by using gson issue

I'm try to convert JsonObject to String by using GSON library. But the result output will have one more layer of parent "map" wrap up the json. Please let me know any wrong i did why the layer of parent "Map" will appear?
i do even try to covert the bean by using new Gson().toJson(bean); but the output result also have one more layer of parent "map" wrap up the json.
Condition i need to fulfil by use
1) Mutable object
2) GSON
3) method might handle other object Type
Maven project using as bellow library:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Java code bellow(example for understand only not the real code, will using in T):
List<JSONObject> records = new ArrayList <JSONObject> ();
JSONObject bean = new JSONObject();
bean.put("A", "is A");
bean.put("B", "is B lah");
bean.put("C", "is C lah");
bean.put("D", "is D");
records.add(bean);
String JSONBody2 = new Gson().toJson(records);
I expect the output is
[{"D":"is D","A":"is A","B":"is B lah","C":"is C lah"}]
but the actual output is
[{"map":{"D":"is D","A":"is A","B":"is B lah","C":"is C lah"}}]
Actual code is as below
public String Json( String json, List<T> list) {
String JSONBody = new Gson().toJson(list);
}
I need to Serialization by using gson that's why i put the T. but i don't have idea why the "map" is appeared here. as previously it work without Parent "Map" wrap up. (same code and same library just new recreated project but having this issue)
try
String JSONBody2 = record.toString());
will give you [{"A":"is A","B":"is B lah","C":"is C lah","D":"is D"}]
You can get more better understanding of type conversion from this link https://stackoverflow.com/a/27893392/4500099
Although others have already answered it, i would like to highlight one important learning. There are 2 ways to convert JsonObject to string.
One is new Gson().toJson(..) and other is JsonObject.toString().
Although both will produce same results in many cases but if the JsonObject has some string fields containing valid urls or base64 ecoded values, the first method will convert & and = into corresponding utf-8 representative characters which will make your urls and base64 ecoded values corrupted. However, second method keep those values intact.
Use JSONArray instead of List , it will give you the desired output:
JSONArray records = new JSONArray();
JSONObject bean = new JSONObject();
bean.put("A", "is A");
bean.put("B", "is B lah");
bean.put("C", "is C lah");
bean.put("D", "is D");
records.put(bean);
String JSONBody2 = new Gson().toJson(records);
Don't use a JSON Object. Just use Object
List<Object> records = new ArrayList<>();
Map<String, String> bean = new HashMap<>();
bean.put("A", "is A");
bean.put("B", "is B lah");
bean.put("C", "is C lah");
bean.put("D", "is D");
records.add(bean);
String JSONBody2 = new Gson().toJson(records);
System.out.println(JSONBody2);
Output is
[{"A":"is A","B":"is B lah","C":"is C lah","D":"is D"}]
If you look at the implementation of org.json.JSONObject, it internally contains a variable called map where it stores all the data. This is the constructor
public JSONObject() {
this.map = new HashMap<String, Object>();
}
When GSON tries to convert to JSON, it just recursively looks into the object and converts all variables to JSON. So in this case, it converts the internal map, which shows up in the Json output.

Special characters break Json

I need to work with Jsons containing loads of special characters and spaces. I've read somewhere else here on stack that the Gson library (for Java) does a very good job so I'm using that. While using the fromJson(Json string, object class) method to turn a Json string into an object, I noticed that as soon as the data in the string contains any special character or white space, an exception is thrown (Unterminated object). Removing the special characters makes it work as intended.
To better exemplify the situation:
ArrayList<Person> people = new ArrayList<Person>();
Person p1 = new Person("Matteo", 999);
Person p2 = new Person("Adam", 999);
Person p3 = new Person("Steve", 999);
people.add(p1);
people.add(p2);
people.add(p3);
String json = new Gson().toJson(people);
System.out.println(json);
ArrayList people2 = new Gson().fromJson(json, ArrayList.class);
for (int i = 0; i < people2.size(); i++) {
Person pn = new Gson().fromJson(people2.get(i).toString(), Person.class);
System.out.println(people2.get(i).toString());
System.out.println(pn.name);
}
class Person {
String name;
int age;
Person(String cname, int cage) {
name = cname;
age = cage;
}
}
The code above works as intended, BUT if instead of Matteo I type Ma:tteo or Ma tteo or any other string that contains special characters then it breaks.
So is there a way to circumvent this issue? Alternatively is there a better solution than using this library?
Thanks in advance
Gson does its work fine.
There are two problems with how you are using the Gson library:
You are using fromJson(String, Class<T>) in conjunction with generics. The documentation states that when using generics, you should use fromJson(String, Type):
For the cases when the object is of generic type, invoke fromJson(String, Type).
You are first deserializing the JSON string into a Java structure – in your case an ArrayList – and then you are looping over it, and for each object, you are deserializing it again, relying on the toString() method of the object contained in the ArrayList. As a matter of fact, your list does not contain Person objects at all, instead, it contains LinkedTreeMap objects from the com.google.gson.internal package. You can get the object's class by calling people2.get(i).getClass().
You really don't need to walk over the elements of this ArrayList and deserialize the elements yourself. If it was required to walk over each list contained in your structure, it would be a world of hurt when that structure was more complex than yours.
Simply get rid of your for-loop and replace your toJson(String, Class<T>) call with a call to fromJson(String, Type). That's all.
// We're using the TypeToken class, to handle generic types
Type type = new TypeToken<List<Person>>() { }.getType();
List<Person> newPeople = new Gson().fromJson(json, type);
// Print all names
newPeople.stream()
.map(t -> t.name)
.forEach(System.out::println);
Notes
A part of the source of the problem is that you are using a raw type (ArrayList). Don't use raw types, they are only allowed for backward compatibility.
I need to work with Jsons containing loads of special characters and spaces.
It's still not clear what you mean with special characters. The JSON standard clearly defines what is allowed and what is not. Your JSON string should follow the standards, and then you're good to go.
Try with this code.
ArrayList<Person> people = new ArrayList<Person>();
Person p1 = new Person("Ma:tteo", 999);
Person p2 = new Person("Adam", 999);
Person p3 = new Person("Steve", 999);
people.add(p1);
people.add(p2);
people.add(p3);
Gson gson = new Gson();
String json = gson.toJson(people);
System.out.println(json);
List<Person> personList = gson.fromJson(json, new TypeToken<List<Person>>(){}.getType());
for (int i = 0; i < personList.size(); i++) {
Person person = personList.get(i);
System.out.println(person.toString());
System.out.println(person.name);
}

Gson - Merge multiple JSONs objects into one JSON

I have a case where I need to merge multiple JSONs objects into one JSON.
A single response looks like this:
{"name":"MyName"}
Multiple merged JSON looks like this:
["{\"name\":\"name\"}","{\"name\":\"MyName\"}"]
The problem here is that the child JSONs that I want to include can come either from a Java object or are available as String itself.
MyRequest request = new MyRequest();
request.setName("name");
String singleJson = new Gson().toJson(request);
String fromSomePlaceElse = "{\"name\":\"MyName\"}";;
List<String> list = Lists.newArrayList(singleJson,fromSomePlaceElse);
System.out.println(new Gson().toJson(list));
The above gives me the following output:
["{\"name\":\"name\"}","{\"name\":\"MyName\"}"]
instead of:
[{"name":"MyName"}, {"name":"MyName"}]
I don't want to parse the already existing JSON and do the following:
List<MyRequest> list2 = Lists.newArrayList(request, new Gson().fromJson(fromSomePlaceElse, MyRequest.class));
System.out.println(new Gson().toJson(list2));
Can this be done using Gson ?
Just print it.
List<String> list = Lists.newArrayList(singleJson,fromSomePlaceElse);
System.out.println(list);
Then you can get
[{"name":"name"}, {"name":"MyName"}]
if you want json in form of string,you can directly use ---
new Gson().toJson(yourList, new TypeToken<List<JsonObject>>(){}.getType())
Try the given library to merge any amount of JSON-objects at once. The result can be returned as String or JsonObject (GSON). Please reference the code in this answer.

Deserialize JSON object that has a map using Gson

I've searched the web for a solution, but, the answers I found only help when the JSON file being parsed is solely a map.
I was wondering if there is a way to parse an object that has an HashMap along with other data.
For example:
public class Data
{
String aName;
HashMap<String, Object> objects;
List<String> aExpressions;
}
I can parse the name and expressions but I don't know how to parse the entire JSON object as a whole.
I think it has something to do with type tokens, but that only works if the whole object is a HashMap.
The presence of HashMap in your class does not change how Gson converts it to and from json.
data d = new data();
//set some values
String json = new Gson().toJson(d);
data d2 = new Gson().fromJson( json, data.class);
That's pretty much it.
Since
JSON can represent four primitive types (strings, numbers,
booleans, and null) and two structured types (objects and arrays).
A string is a sequence of zero or more Unicode characters
[UNICODE].
An object is an unordered collection of zero or more name/value
pairs, where a name is a string and a value is a string, number,
boolean, null, object, or array.
An array is an ordered sequence of zero or more values.
Gson acts 2 ways:
you can let Gson deserialize creating a combination of maps, lists and primitives or
you can specify exactly the kind of object you want, and through reflection, it will fill the desidered fields.
You can mix these two approaches and of course you can do a lot more to solve all your parsing cases (like using custom type adapters).
I prepared you a little example using your class that shows how Gson can parse your data using a combination of maps/list/primitives or passing your class (that has a mixed approach).
package stackoverflow.questions;
import java.util.*;
import com.google.gson.Gson;
public class Q20154323 {
public static class Data {
public String aName;
public HashMap<String, Object> objects;
public List<String> aExpressions;
#Override
public String toString() {
return "Data [aName=" + aName + ", objects=" + objects + ", aExpressions=" + aExpressions + "]";
}
}
public static void main(String[] args) {
Data d = new Data();
d.aName = "Test";
d.objects = new HashMap<>();
d.aExpressions = new ArrayList<>();
d.objects.put("key1", 1L);
d.objects.put("key2", new Date());
d.aExpressions.add("Stack");
d.aExpressions.add("Overflow");
Gson g = new Gson();
String json = g.toJson(d);
System.out.println("As JSON: " +json);
Data d2 = g.fromJson(json, Data.class);
System.out.println("As \"casted\" data type: " + d2);
Object o3 = g.fromJson(json, Object.class);
System.out.println("As \"free\" object: " + o3);
}
}
and this is the execution. It shows you two way of parsing the JSON string that I created using your initial class.
As JSON: {"aName":"Test","objects":{"key2":"Nov 23, 2013 1:33:23 AM","key1":1},"aExpressions":["Stack","Overflow"]}
As "casted" data type: Data [aName=Test, objects={key2=Nov 23, 2013 1:33:23 AM, key1=1.0}, aExpressions=[Stack, Overflow]]
As "free" object: {aName=Test, objects={key2=Nov 23, 2013 1:33:23 AM, key1=1.0}, aExpressions=[Stack, Overflow]}
You can use one or other approach as your needs.
About the TypeToken, due to generics erasure, something like this
List<Data> list = new Gson().parse(aJsonString, List<Data>.class)
won't work, you have to do something like
Type listType = new TypeToken<List<Data>>() {}.getType();
List<Data> list = new Gson().parse(aJsonString, listType.class)
but this case applies, pratically, when your JSON is an array and you want to deserialize it into a list of custom classes.

how to parse multiple json objects with no name

im having some trouble parsing json. I have json in the format of:
{"blah":"blah","blah":"blah"}
{"blah":"blah","blah":"blah"}
{"blah":"blah","blah":"blah"}
Here is the link to the JSON: http://gerrit.aokp.co/query?format=JSON&q=status:merged&age:1d
I cant make this a jsonobject and iterate over it. I currently have it as a string.
Is there a way to iterate over this? there will be over 500.
I tried making it an array by adding square brackets around it, but it didnt work because i needed to divide them with commas. I cant manipulate this by hand because im getting it from the web. So i tried this.
jsonString = jsonString.replaceAll("}(?!,)", "},");
the reason im adding the negative comma is that sometimes i might have a jsonobject inside of of these objects so I only want to add a comma in front of the '}' without commas.
when i do the replaceall i get this error.
Error in fetching or parsing JSON: java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 1:
}(?!,)
^
What am I doing wrong or is there an easier way to do this that im looking over?
EDIT:
Oh yes, I need to implement this in java because this is in an android app.
here is an example how you can accomplish what you want using Jackson's ObjectMapper.
ObjectMapper om = new ObjectMapper();
try {
List<Object> obj = om.readValue(yourJsonString, new TypeReference<List<Object>> () { });
} catch (IOException e1) {
e1.printStackTrace();
}
Now you will have a list of each of the individual Objects in your JSON string. To take it a step further you could create a POJO for the Object you are parsing.
Something like:
public class MyObject{
private String project;
private String branch;
}
That is just an exmple, you would need to define a property for each json property.
Then you can turn :
List<Object> obj = om.readValue(yourJsonString, new TypeReference<List<Object>> () { });
Into
List<MyObject> obj = om.readValue(yourJsonString, new TypeReference<List<MyObject>> () { });
Hope this helps!
From the link you posted, it looks like there are newlines between objects (and only between objects). If that's right, I'd approach it like this:
String[] items = dataFromWeb.split("\n");
String asJSONArrayString = Arrays.toString(items);
JSONArray jsonArray = new JSONArray(asJSONArrayString);
This splits the data at newlines, then joins it together with commas between elements and brackets around the whole thing.
JSONObject jObject = null;
mJsonString = downloadFileFromInternet(urlString);
jObject = new JSONObject(mJsonString);
This will get you json object.
This is the way to get json array from json object:
JSONArray jsonImageArray = jObject.getJSONArray("your string");

Categories

Resources