java - how to parse String back to List of Map - java

I have a String with this format (it's a List of Map assigned to a string var)
[{code=1, data=Male} , {code=2, data=Female}]
.. how can I parse the above string back to list of map.. without using any String.split function (cause it is prone to error)
here is the code I've tried.. but with split function..
if(!string.equals("")){
String[] listArray = string.split(DELIMITER);
for (int i=0;i<listArray.length;i++) {
String val=listArray[i];
val = val.replaceAll("[\\{\\}]", "");
//Gets the value from DATA key
if(val.split(EQDELIMITER)[0].trim().equalsIgnoreCase("DATA")){
try{
map.put("DATA", val.split(EQDELIMITER)[1]);
}catch(IndexOutOfBoundsException e){
map.put("DATA", "");
}
}
//Gets the value from CODE key
if(val.split(EQDELIMITER)[0].trim().equalsIgnoreCase("CODE")){
try{
map.put("CODE", val.split(EQDELIMITER)[1]);
}catch(IndexOutOfBoundsException e){
map.put("CODE", "");
}
}
if (map != null && map.size() >= 2) {
//add map to codeList
codeList.add(map);
map = new HashMap<String,Object>();
}
}
}

If you are flexible enough to use a library, then Use google's GSON
Map map = gson.fromJson(jsonString, Map.class);
As you want a list of Map, wo you can also use TypeToken
List<Map<E,V>> list= new Gson().fromJson(jsonString,
new TypeToken<List<Map<E, V>>() {}.getType());
replace E, V with actual types.

Why can't you go for object Mapper..?(org.codehaus.jackson.map.ObjectMapper)
it would be something like this...
ObjectMapper mapper= new ObjectMapper();
Map<Integer,String> map = mapper.readValue(yourString,org.codehaus.jackson.type.TypeReference.TypeReference<Map<Integer,String>>() {
});

Related

JSON getting nested in a POJO

I have a POJO class as:
public class D{
private JSONObject profileData;
public JSONObject getProfileData ()
{
return profileData;
}
public void setProfileData (JSONObject profileData)
{
this.profileData = profileData;
}
}
Now I populate this class like:
for (int i =0; i<identities.size();i++){
D d = new D();
d.setProfileData(profileData);
dList.add(d);
}
I create JSON object for profileData from GSON using a HashMap:
profileDataInJson = new JSONObject(gson.toJson(map1));
Where the signature of profileDataInJson is: JSONObject profileDataInJson = null;
Now the resultant JSON is like:
"profileData":{"map":{"ioCinema":"firstValue","ioSIMAvailable":"firstKey","Name":"onePair"}}
Wherein I get an unwanted object called map inserted in my main profileData object.
However when I print this inside the loop I get
{`"ioCinema":"firstValue","ioSIMAvailable":"firstKey","Name":"onePair"}`
Whish is exactly what I want inside profileData object, without nesting the map object.
How do I solve this?
"I am already aware that I can achieve this by converting the type of profileData in D class from JSONObject to String, which will induce escape characters - However I am looking for a generic solution"
EDIT:
map1 is constructed in two ways, depending on user input and both ways are as follows:
if (args.length >= 4 && args[1].equalsIgnoreCase("onePair")) {
map1 = new HashMap<>();
String key1 = args[2];
String value1 = args[3];
map1.put(key1, value1);
profileDataInJson = new JSONObject(gson.toJson(map1));
}
And:
if (args.length >= 1 && args[0].equalsIgnoreCase("update")) {
if (args.length >= 2)
profileData.setName(args[1] != null ? args[1] : "");
if (args.length >= 3)
profileData.setSIMAvailable(args[2] != null ? args[2] : "");
profileDataInJson = new JSONObject(profileData);
}
Signature: ProfileData profileData = new ProfileData();
The thing which puzzles me is when I try to traverse profileData and try to fetch the json object by name "map" I get a nullPointer exception
You don't need to use Gson to convert hashmap to a json object.
Simply use:
profileDataInJson = new JSONObject(map);
Add custom serializer to Gson, so that Gson serialize the org JSON as expected by you.
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(JSONObject.class, new JsonSerializer<JSONObject>() {
#Override
public JsonElement serialize(final JSONObject src, final Type typeOfSrc,
final JsonSerializationContext context) {
return new JsonParser().parse(src.toString()).getAsJsonObject();
}
});
gsonBuilder.create().toJson(map1);
This will return {"ioCinema":"firstValue","ioSIMAvailable":"firstKey","Name":"onePair"}

How can I convert Json String to List<HashMap<String, String>>?

I creating compare data A and each data using Java.
First, I did extract array data from txt file (array type in file).
Second, I have a Json String data in my database (MySQL column type : JSON).
I parsed txt file and make List
FileInputStream fstream = new FileInputStream(Path);
List<HashMap<String, String>> list = list(fstream);
public List<HashMap<String, String>> list(FileInputStream fstream) {
BufferedReader buff = new BufferedReader(new InputStreamReader(fstream));
List<HashMap<String, String> list = new ArrayList<>();
try {
while ((strLine = buff.readLine()) != null) {
s = strLine.split(" ");
HashMap<String, String> map = new HashMap<>();
pts = s[4].split(":")[1];
ptstime = s[5].split(":")[1];
map.put("pts", pts);
map.put("ptstime", getDurationString(ptstime));
if (pts_itv.equals("0") && ptstime_itv.equals("00:00")) {
map.put("pts_itv", "0");
map.put("ptstime_itv", "00:00");
}
else {
map.put("pts_itv", String.valueOf(Long.parseLong(pts) - Long.parseLong(pts_itv)));
map.put("ptstime_itv", getDurationString(String.valueOf(String.format("%.4f", Double.parseDouble(ptstime) - Double.parseDouble(ptstime_itv)))));
}
pts_itv = pts;
ptstime_itv = ptstime;
list.add(map);
}
}
catch (IOException ex) {
LOG.error("ERROR : " + ex.getLocalizedMessage() + ", " + ex.getMessage());
}
finally {
try {
buff.close();
} catch (IOException ex) {}
}
return list;
}
Extraction data
[{pts_itv=0, ptstime=00:00:00.112792, pts=2707, ptstime_itv=00:00}, {pts_itv=192192, ptstime=00:00:08.12079, pts=194899, ptstime_itv=00:00:08.80}, {pts_itv=128128, ptstime=00:00:13.4595, pts=323027, ptstime_itv=00:00:05.3387}, {pts_itv=277277, ptstime=00:00:25.127, pts=600304, ptstime_itv=00:00:11.5532}]
I can get index key, object key.
list.get(0).get("pts_itv");
And Second data (SELECT Query from MySQL (Column JSON Type))
rs = Web.getInstance().getList(idx); //get data by sql query
jObj = (JSONObject) new JSONParser().parse(rs);
jArr = (JSONArray) jObj.get("data");
for (int i = 0; i < jArr.size(); i++) {
JSONObject Jarr = (JSONObject) jArr.get(i);
System.out.println(Jarr.get("PtsData"));
}
PtsData is
[{"pts": "81831", "pts_itv": "0", "ptstime": "00:00:03.40963", "ptstime_itv": "00:00"}, {"pts": "127877", "pts_itv": "46046", "ptstime": "00:00:05.32821", "ptstime_itv": "00:00:01.9186"}, {"pts": "157907", "pts_itv": "30030", "ptstime": "00:00:06.57946", "ptstime_itv": "00:00:01.2512"}]
java.lang.String
I want PtsData convert to first data type. How can I convert PtsData to List type?
Here are some suggestions to solve this problem.
Don't use String operations un-till they are really needed, you can avoid split by using JSON library to parse JSON data. More code you write, more bugs you introduce and more maintenance it need.
Use Object modelling. This would be more readable to use it in HashMap. Create an object model by defining peroperties pts, pts_itv, ptstime, ptstime_itv.Then choose your key and value. Define equals and hashcode. Then check equality of objects either with your own way to or use equals.

Convert JSON object with duplicate keys to JSON array

I have a JSON string that I get from a database which contains repeated keys. I want to remove the repeated keys by combining their values into an array.
For example
Input
{
"a":"b",
"c":"d",
"c":"e",
"f":"g"
}
Output
{
"a":"b",
"c":["d","e"],
"f":"g"
}
The actual data is a large file that may be nested. I will not know ahead of time what or how many pairs there are.
I need to use Java for this. org.json throws an exception because of the repeated keys, gson can parse the string but each repeated key overwrites the last one. I need to keep all the data.
If possible, I'd like to do this without editing any library code
As of today the org.json library version 20170516 provides accumulate() method that stores the duplicate key entries into JSONArray
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("a", "b");
jsonObject.accumulate("c", "d");
jsonObject.accumulate("c", "e");
jsonObject.accumulate("f", "g");
System.out.println(jsonObject);
Output:
{
"a":"b",
"c":["d","e"],
"f":"g"
}
I want to remove the repeated keys by combining their values into an array.
Think other than JSON parsing library. It's very simple Java Program using String.split() method that convert Json String into Map<String, List<String>> without using any library.
Sample code:
String jsonString = ...
// remove enclosing braces and double quotes
jsonString = jsonString.substring(2, jsonString.length() - 2);
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String values : jsonString.split("\",\"")) {
String[] keyValue = values.split("\":\"");
String key = keyValue[0];
String value = keyValue[1];
if (!map.containsKey(key)) {
map.put(key, new ArrayList<String>());
}
map.get(key).add(value);
}
output:
{
"f": ["g"],
"c": ["d","e"],
"a": ["b"]
}
In order to accomplish what you want, you need to create some sort of custom class since JSON cannot technically have 2 values at one key. Below is an example:
public class SomeClass {
Map<String, List<Object>> values = new HashMap<String, List<Object>>();
public void add(String key, Object o) {
List<Object> value = new ArrayList<Object>();
if (values.containsKey(key)) {
value = values.get(key);
}
value.add(o);
values.put(key, value);
}
public JSONObject toJson() throws JSONException {
JSONObject json = new JSONObject();
JSONArray tempArray = null;
for (Entry<String, List<Object>> en : values.entrySet()) {
tempArray = new JSONArray();
for (Object o : en.getValue()) {
tempArray.add(o);
}
json.put(en.getKey(), tempArray);
}
return json;
}
}
You can then retrieve the values from the database, call the .add(String key, Object o) function with the column name from the database, and the value (as the Object param). Then call .toJson() when you are finished.
Thanks to Mike Elofson and Braj for helping me in the right direction. I only wanted to have the keys with multiple values become arrays so I had to modify the code a bit. Eventually I want it to work for nested JSON as well, as it currently assumes it is flat. However, the following code works for what I need it for at the moment.
public static String repeatedKeysToArrays(String jsonIn) throws JSONException
{
//This assumes that the json is flat
String jsonString = jsonIn.substring(2, jsonIn.length() - 2);
JSONObject obj = new JSONObject();
for (String values : jsonString.split("\",\"")) {
String[] keyValue = values.split("\":\"");
String key = keyValue[0];
String value = "";
if (keyValue.length>1) value = keyValue[1];
if (!obj.has(key)) {
obj.put(key, value);
} else {
Object Oold = obj.get(key);
ArrayList<String> newlist = new ArrayList<String>();
//Try to cast as JSONArray. Otherwise, assume it is a String
if (Oold.getClass().equals(JSONArray.class)) {
JSONArray old = (JSONArray)Oold;
//Build replacement value
for (int i=0; i<old.length(); i++) {
newlist.add( old.getString(i) );
}
}
else if (Oold.getClass().equals(String.class)) newlist = new ArrayList<String>(Arrays.asList(new String[] {(String)Oold}));
newlist.add(value);
JSONArray newarr = new JSONArray( newlist );
obj.put(key,newarr);
}
}
return obj.toString();
}

how do I find out a JSON Object return JSON Array or string in android

I have a json like the following. how do I find out a JSON Object return JSON Array or string in android.
{
"green_spots": [
......
],
"yellow_spots": "No yellow spot available",
"red_spots": "No red spot available"
}
The JSON objects retrurn Array when values is present else return a String like "No green/red/yellow spot available". I done the with following way. but is there any other way to do? because alert string is changed the If will not work.
JSONObject obj = new JSONObject(response);
String green = obj.getString("green_spots");
// Green spots
if ("No green spot available".equalsIgnoreCase(green)) {
Log.v("search by hour", "No green spot available");
} else {
JSONArray greenArray = obj.getJSONArray("green_spots");
....
}
Object object = jsonObject.get("key");
if (object instanceof JSONObject) {
// It is json object
} else if (object instanceof JSONArray) {
// It is Json Array
} else {
// It is a String
}
You can use instanceof
instead of getString do just obj.get which will return an Object, check if the object is instanceof String or JSONArray
EDIT:
here is a bit of sample code to go with this:
Object itineraries = planObject.get("itineraries");
if (itineraries instanceof JSONObject) {
JSONObject itinerary = (JSONObject) itineraries;
// right now, itinerary is your single item
}
else {
JSONArray array = (JSONArray) itineraries;
// do whatever you want with the array of itineraries
}
JSONObject obj = new JSONObject(response);
JSONArray greenArray = obj.getJSONArray("green_spots");
if(greenArray!=null){
do your work with greenArray here
}else{
Log.v("search by hour", "No green spot available");
}
Simple just print the object like Log.e("TAG","See>>"JsonObject.toString);
if response is in {} block then it is object if it is in [] its array
Warning: This information may be superfluous, but it might prove to be an alternative approach to this problem.
You can use Jackson Object Mapper to convert a JSON file to a HashMap.
public static HashMap<String, Object> jsonToHashMap(
String jsonString) {
Map<String, Object> map = new HashMap<String, Object>();
ObjectMapper mapper = new ObjectMapper();
try {
// convert JSON string to Map
map = mapper.readValue(jsonString,
new TypeReference<HashMap<String, Object>>() {
});
} catch (Exception e) {
e.printStackTrace();
}
return (HashMap<String, Object>) map;
}
This automatically creates a HashMap of appropriate objects. You can then use instanceof or figure out another way to use those objects as appropriate/required.

Use HashMap in XMLRPC result

I am new in Android development, and I am trying to receive a HashMap in RESULT by using XMLRPC but every time it's crash the application, this is my code please advice me :
Object RESULT = XMLRPCClient.callEx(methodname,new Object[] {params});
Map FRESULT= (Map) RESULT;
I have been dealing with this also and managed to get the values this way:
try {
Object[] answer = (Object[]) client.call("call", sessionId, method, params);
HashMap map = (HashMap) answer[0]; // get first item of the response because in my case the response was an array of Objects with one item in it holding the HashMap
Object[] records = (Object[]) map.get("records"); // I only needed values from "records" key
for (int i = 0; i < records.length; i++) {
HashMap record = (HashMap) records[i]; // create another map from the records values, in my case uid's of categories
Category cat = new Category(); // creating new instance of my Category class
cat.setCatUid((String) record.get("uid")); // calling a method of the Category class to set Uid to the value from record HashMap
m_categories.add(cat); // this adds it to my ArrayList<Category>
}
} catch (XMLRPCException e) {
Log.e(method, "Exception", e);
}
I'm sure it's a mess, I'm noob in Java myself, but it worked for me. Hope it helps :)
Now the Application pass this peacefully after implementing :
Object RESULT = XmlRpcConnect.ServerCall_a(method,new Object[] {params});
Map<String, Object> FRESULT= (HashMap<String, Object>) RESULT;
with some changes in my XmlRpcConnect Class:
#SuppressWarnings("unchecked");
public static Object ServerCall_a(String method, Object[] params){
XMLRPCClient client = new XMLRPCClient(server);
HashMap<String, Object> result=null;
try{
result = (HashMap<String, Object>) client.callEx(method, params);
}
catch(XMLRPCFault f){
// result = ("Fault message: " + f.getMessage());
}
catch(XMLRPCException e){
// result = ("Exception message: " + e.getMessage());
}
return result;
}
but when trying to extract the values it's crash again , any advice :
if (FRESULT.get("status") == null) {
result = (String) FRESULT.get("status");
toastDialog(result);
}

Categories