How to read multiple values from the json object in java - java

I want to read the values which is there in json object
example :
remote":{"ip":"127.0.0.1","port":35637}
How can I convert this ip and port into string in java?

Here's how to use the Google Gson library to extract the two scalar values from your structure:
import com.google.gson.Gson;
import java.util.Map;
class Scratch {
public static void main(String[] args) {
// Input data structure - note the added curly braces to make the input
// a valid JSON dictionary and the messy escaping of double quotes. You
// will usually read JSON from a file or have it come in from an API call,
// so escaping like this doesn't come up a lot.
String json = "{\"remote\":{\"ip\":\"127.0.0.1\",\"port\":35637}}";
// Create an instance of the Gson encoder/decoder
Gson gson = new Gson();
// Decode the JSON to a Java data structure
Map<String, Map<String, Object>> map = gson.fromJson(json, Map.class);
// Extract the "remote" key to get the inner dictionary
Map<String, Object> remote = map.get("remote");
// Grab the two inner values. Numbers in JSON are doubles in Java
String ip = (String)remote.get("ip");
double port = (double)remote.get("port");
System.out.println(ip);
System.out.println((int)port);
}
}
Result:
127.0.0.1
35637

Related

Why can't read a .json?

I want to read a .json using library json-simple, my json file is:
{
"Subjects": {
"subject1": "MIS",
"subject2": "DBMS",
"subject3": "UML"
}
}
And my code is:
import java.io.*;
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;
public class JSONReadFromTheFileTest {
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try{
Object obj = parser.parse(new FileReader("/Users/User/Desktop/course.json"));
JSONObject jsonObject = (JSONObject)obj;
JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
Iterator iterator = subjects.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}catch(Exception e){
e.printStackTrace();
}
}
}
I would like to get in console:
subject1: MIS
subject2: DBMS
subject3: UML
But instead of that, I just get the next error:
java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to org.json.simple.JSONArray
at project.Main(Main.java:11)
But I searched in internet, and I found that if I change sintaxys of the .json in the next way:
{
"Subjects": [
"subject1: MIS",
"subject2: DBMS",
"subject3: UML"
]
}
I get in console what I want:
subject1: MIS
subject2: DBMS
subject3: UML
And you may think my problem is solved, but not yet, because I want to read the json file in the first way.
I hope someone can help me. Thanks in advance.
The first example shows a Subjects key containing a single object with several properties (subject1, subject2, etc).
Consider those properties like the member variables of a class.
In order to let you better understand if the class is Person those variables could be name and surname.
What you try to achieve in your code is extracting a JSONArray from the JSON you are providing.
Going back to the example for Person the array could be - sorry for the silly example - an Array containing phone numbers.
So what you are expecting is that one of the member properties of the class is an array.
This is not possible in the first example because the first example does not contain a json array.
This line extracts the whole json object:
JSONObject jsonObject = (JSONObject)obj;
This one tries to get an array out but no array is there in the first example:
JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
Square brackets represent an array, which you've casted the getter into.
The second json shown is more correct for the code you've written, however, arrays cannot hold key-value pairs, so that's why you've made second JSON have an array of strings
To parse the first file, you'd need to start with
JSONObject subjects = (JSONObject)jsonObject.get("Subjects")
If you have full control over the file, I'd suggest just storing ["MIS", "DBMS", "UML"] then write a simple loop
for (int i = 0; i < jsonArray.length; i++) {
System.out.printf("subject%d: %s%n", i+1, jsonArray.get(i));
}
To make your code work with your json, you should not use JSONArray for "Subjects" but instead JSONObject. The reason is that [ and ] indicates beginning and ending of array element in json which is represented by JSONArray. If you have { and } element then its object represented by JSONObject. zz So replace this:
JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
Iterator iterator = subjects.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
with following (I have not compiled it):
JSONObject subjects = (JSONObject)jsonObject.get("Subjects");
for(Iterator iterator = subjects.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
System.out.println(key + ": " + subjects.get(key));
}
As others mentioned you should replace JSONArray with JSONObject in your code. But I would suggest to switch to different JSON library all together. I would recommend to use Json-Jackson library. Also, there is another library that provides a wrapper over Json-Jackson library. It has JsonUtils class that can simply parse your JSON in one line. Just read first your Json from file into a String jsonString and do this.
Map<String, Object> myMap = JsonUtils.readObjectFromJsonString(jsonString, Map.class);
You will get a Map with one key "Subjects" that will have a value of a Map with your 3 keys and values:
subject1: MIS
subject2: DBMS
subject3: UML
Here is the JavaDoc for the JsonUtils class. The library could be found as Maven artifact and on Github (including source code and Javadoc).

create json using Google Gson

I want make json
records":[ {"MON_PRIORITY":"","MON_ICR_ACCNO":"100000010010","MON_REPORT_DATE":"","MON_STATUS":"",
But my json is
{"MON_PRIORITY":"","MON_ICR_ACCNO":"100000010010","MON_REPORT_DATE":"","MON_STATUS":"",
My jsp code is
HashMap jsonRecordval = (HashMap) hshValues.get("jsonRecord");
String json="";
json = new Gson().toJson(jsonRecordval );
Thanks..
What you're getting is the JSON produced by a Hashmap. e.g. {"key":"value"}. Breaking it down piece by what, your desired json is a representation of an object { with a records field "records" that contains an array [ of the contents of your hashmap {"key":"value"}
To do that, it's easiest to create an object with instance variables corresponding to the fields to expected output. Something like
public class JsonRecords {
private final List<HashMap> records = new ArrayList<>;
public JsonRecords(HashMap recordsVal) {
records.add(recordsVal);
}
//Getters and setters
}
Then use it to build your JSON
HashMap jsonRecordval = (HashMap) hshValues.get("jsonRecord");
String json = new Gson().toJson(new JsonRecords(jsonRecordval));

How to create json, sorted on keys, using gson?

I need to create constant json string or a json sorted on keys. What do I mean by constant json string? Please look into following code sample, which I created.
My Code 1:
public class GsonTest
{
class DataObject {
private int data1 = 100;
private String data2 = "hello";
}
public static void main(String[] args)
{
GsonTest obj=new GsonTest();
DataObject obj2 = obj.new DataObject();
Gson gson = new Gson();
String json = gson.toJson(obj2);
System.out.println(json);
}
}
Output 1:
{"data1":100,"data2":"hello"}
My Code 2:
public class GsonTest
{
class DataObject {
private String data2 = "hello";
private int data1 = 100;
}
public static void main(String[] args)
{
GsonTest obj=new GsonTest();
DataObject obj2 = obj.new DataObject();
Gson gson = new Gson();
String json = gson.toJson(obj2);
System.out.println(json);
}
}
Output 2:
{"data2":"hello","data1":100}
If you see, if I switch variables (data1 & data2 in DataObject class), I get different json. My objective to get same json, even if somebody changes position of the class variables. I get it when somebody adds new variables, json would change. But json shouldn't change when variables are moved around. So, my objective is to get standard json, possibly in sorted keys order for same class. If there is nested json, then it should be sorted in the nested structure.
Expected output on run of both the codes:
{"data1":100,"data2":"hello"} //sorted on keys!! Here keys are data1 & data2
I understand, I need to change something in String json = gson.toJson(obj2); line, but what do I have to do?
Why I need them to be order?
I need to encode the json string and then pass it to another function. If I change the order of keys, even though value remain intact, the encoded value will change. I want to avoid that.
First of all, the keys of a json object are unordered by definition, see http://json.org/.
If you merely want a json string with ordered keys, you can try deserializing your json into a sorted map, and then serialize the map in order to get the sorted-by-key json string.
GsonTest obj=new GsonTest();
DataObject obj2 = new DataObject();
Gson gson = new Gson();
String json = gson.toJson(obj2);
TreeMap<String, Object> map = gson.fromJson(json, TreeMap.class);
String sortedJson = gson.toJson(map);
Like others have mentioned that by design JSON is not supposed to have sorted keys in itself. You can also come up with a recursive solution to do it. I won't say my solution is very efficient but it does the intended job. Please have a look at the following piece of code.
private static JsonObject sortAndGet(JsonObject jsonObject) {
List<String> keySet = jsonObject.keySet().stream().sorted().collect(Collectors.toList());
JsonObject temp = new JsonObject();
for (String key : keySet) {
JsonElement ele = jsonObject.get(key);
if (ele.isJsonObject()) {
ele = sortAndGet(ele.getAsJsonObject());
temp.add(key, ele);
} else if (ele.isJsonArray()) {
temp.add(key, ele.getAsJsonArray());
} else
temp.add(key, ele.getAsJsonPrimitive());
}
return temp;
}
Input:
{"c":"dhoni","a":"mahendra","b":"singh","d":{"c":"tendulkar","b":"ramesh","a":"sachin"}}
Output:
{"a":"mahendra","b":"singh","c":"dhoni","d":{"a":"sachin","b":"ramesh","c":"tendulkar"}}
Perhaps a work around is for your class wrap a TreeMap which maintains sort order of the keys. You can add getters and setters for convenience. When you gson the TreeMap, you'll get ordered keys.

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.

JavaScript objects in Java?

How do I loop over a string of item and create an object based on that?
I currently have this code:
public static Object ParseParams(String string)
{
Object params = new Object();
String[] lines = string.split("\n");
for(String line : lines)
{
String[] splittedLine = line.split("=");
params[splittedLine[0]] = splittedLine[1]; //JavaScript syntax, not Java!
}
return params;
}
The input string is in this format:
param1=value1
param2=value2
foo=bar
How do I fix the problematic line?
Edit
Sometimes the string would look like this:
foo=bar
param=1=hello
param=2=world
Would it be possible with Maps in Java to get the output like this:
foo
bar
param
1
hello
2
world
So the Maps are sometimes nested, and it you would retrieve hello by calling params.get("param").get("1");
It sounds like you want either a Map, or a JSON library.
Maps
public static Map<String, String> ParseParams(String string)
{
Map<String, String> params = new HashMap<String, String>();
String[] lines = string.split("\n");
for(String line : lines)
{
String[] splittedLine = line.split("=");
params.put(splittedLine[0], splittedLine[1]);
}
return params; // Get a param with params.get(key);
}
In general you'll want a HashMap (fast but not stored in order), but there's also a TreeMap which is slightly slower but stored in order (which can be useful sometimes).
JSON
The format JavaScript uses for objects is used as a general-purpose storage format called JSON (JavaScript Object Notation). This is only useful for storage / printing / network transmission. Internally, Java JSON libraries use maps (JavaScript interpreters probably do too).
There are several Java APIs, but StackOverflow users seem to recommend Json-lib:
public static JSONObject ParseParams(String string)
{
// Note that we need everything from the other method anyway
return JSONObject.fromObject(ParseParams(string));
}
EDIT:
You're already reaching the point where using a Map is strained. I'd suggest just using a class:
class MyStuff {
String foo;
Map<String, String> params;
}
It is possible to nest Maps, like Map<String, Map<String, String>> or Map<String, Object>, but you really should be using classes for this.

Categories

Resources