I'm having trouble trying to make sense of this JSON string.
{
"results":[
{
"user":{
"gender":"female",
"name":{
"title":"miss",
"first":"taylor",
"last":"anderson"
},
"location":{
"street":"3645 dogwood ave",
"city":"roseburg",
"state":"new hampshire",
"zip":"20963"
},
"email":"taylor.anderson49#example.com",
"username":"heavyduck595",
"password":"liverpool",
"salt":"UK`o;9a_",
"md5":"6c8db0305b4591d8d9820d9f8edfd162",
"sha1":"906df4c09f3a87899666cb57bf974bd9b1950ea6",
"sha256":"3b12f5e51688578f845bef8ae1750d3e263c2010691010a80ce632a6b2323c03",
"registered":"1359027425",
"dob":"16243995",
"phone":"(934)-888-7068",
"cell":"(727)-467-8384",
"SSN":"697-20-6143",
"picture":"http://api.randomuser.me/0.3/portraits/women/30.jpg"
},
"seed":"5eaf02877746c7e",
"version":"0.3"
}
]
}
It's the first time I've really used JSON and want to try and interpret it appropriately. This is the code i have thus far:
static class Results{
String results;
}
static class User{
String gender;
String name;
String location;
List<Results> items;
}
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
public void larry() throws Exception{
String json = readUrl("http://api.randomuser.me/");
System.out.println(json);
Gson gson = new Gson();
User page = gson.fromJson(json, User.class);
System.out.println(page.name);
for (Results item : page.items)
System.out.println(" " + item.results);
}
There is nothing particularly complicated about JSON, or mapping it to your own Java classes. You just have to understand the basic structure.
Your JSON is an object that has exactly one field; results. This is what {} means:
{ "results": ... }
That field holds an array. That's the [].
{ "results": [ ... ] }
That array holds another object (presumably you'd have more than one in an array, but the JSON you've posted just has one). That object has three fields, one of which ("user") holds another object with the other two being strings.
To map that to your own classes, you simply make them look like that JSON:
class JsonResult {
List<Result> results; // JSON arrays map to Java Lists
}
class Result {
User user;
String seed;
String version;
}
class User {
String gender;
Name name;
// and so on ...
}
class Name {
String title;
String first;
String last;
}
And so forth. You build classes to match the objects (again, denoted by {}) in the JSON, and structure everything accordingly.
As #HotLicks notes in his comment, you can decide not to map to Java classes and use a "clean" parser. In fact, Gson offers this with it's JsonParser class. This will just parse the JSON to a tree from which you can extract the info you want:
JsonElement element = new JsonParser().parse(yourJsonString);
From there you can access the JSON structure using the field names:
JsonObject root = element.getAsJsonObject();
JsonArray array = root.getAsJsonArray("results");
By accessing the JSON structure you can get to whatever you want.
Related
I create a java URL class which contain my Json data and have some function to obtain back my json data for doing some data comparison, I found out it's might not support by JSONObject for passing the data into the JSONObject. Do I need to use JSONArray in my case because my JSON data have array structure as well?
try
{
JSONObject obj = new JSONObject ();
obj.readJsonFromUrl(theUrl);
System.out.println(obj.toString());
}
catch(MalformedURLException e)
{
System.out.print("your problem here ...1");
}
}
else
{
System.out.print("Can't Connect");
}
I am sure that this is the place give me the error message because it return me this error in my compiler
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method readJsonFromUrl(URL) is undefined for the type JSONObject
there are also some warning message for that the JSONObject readJsonFromUrl method
private static JSONObject readJsonFromUrl(URL theUrl) throws IOException, JSONException {
Anyone can provide me the explaination of how the JSON data work in java? I saw quite number of Java class for JSON which make me confuse for it such as JSONObject, JSONArray , JSONValue. I search some information online but I also not very clear about it since I am very new to JSON data processing This is my sample json data and the data I need is scan_result only
{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"file_info":{
"display_name":"",
"file_size":242,
"file_type":"Not available",
"file_type_description":"Not available",
"md5":"aa69ba384f22d0dc0551ace2fbb9ad55",
"sha1":"09ceb54e65df3d3086b222e8643acffe451a6e8a",
"sha256":"dcb46d6ae2a187f789c12f19c44bbe4b9a43bd200a3b306d5e9c1fcf811dc430",
"upload_timestamp":"2016-11-18T09:09:08.390Z"
},
"process_info":{
"blocked_reason":"",
"file_type_skipped_scan":false,
"post_processing":{
"actions_failed":"",
"actions_ran":"",
"converted_destination":"",
"converted_to":"",
"copy_move_destination":""
},
"profile":"File scan",
"progress_percentage":100,
"result":"Allowed",
"user_agent":""
},
"scan_results":{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"progress_percentage":100,
"scan_all_result_a":"No Threat Detected",
"scan_all_result_i":0,
"scan_details":{
"Ahnlab":{
"def_time":"2016-11-08T15:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":1,
"threat_found":""
},
"Avira":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":133,
"threat_found":""
},
"ClamAV":{
"def_time":"2016-11-08T10:28:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":94,
"threat_found":""
},
"ESET":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":38,
"threat_found":""
}
},
"start_time":"2016-11-18T09:09:08.405Z",
"total_avs":4,
"total_time":250
},
"vulnerability_info":{
}
}
As mentioned here, there are many ways to solve this. Either you have to implement the read, parse operations yourself (#Roland Illig 's answer)
//you have to implement the readJSON method
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
Or you could use a library. The most well-known and widely used libraries are jackson and gson.
The big picture is that you try to "map" your json Object to a class.
You have your json file:
{
"id":1,
"name":"eirini",
"hobbies":["music","philosophy","football"]
}
and a class that represents this file and will store the values (depending on the library that you use there might be different requirements, for example getters, setters etc..)
public class Person {
public int id;
public String name;
public List<String> hobbies = new ArrayList<String>();
public String toString() {
return name +" has the id: " + id + " the following hobbies" + hobbies.get(0) + " " + hobbies.get(2);
}
}
Finally in your main method:
public static void main(String[] args) throws IOException, ParseException {
ObjectMapper mapper = new ObjectMapper();
InputStream input = this.getClass().getResourceAsStream(FILE); //read your file. There are many ways to achieve this.
ObjectMapper mapper = new ObjectMapper(); // just need one
Person eirini = mapper.readValue(input, Person.class);
System.out.println(eirini.toString());
You cannot pass json in url, you can pass it in body. Writing Json to stream body and post it using regular java method.
Here is oracle community url of explanation of your problem.
Required Jar can be downloaded from here.
Test Code Follows:
URL url = new URL("https://graph.facebook.com/search?q=java&type=post");
try (InputStream is = url.openStream();
JsonReader rdr = Json.createReader(is)) {
JsonObject obj = rdr.readObject();
JsonArray results = obj.getJsonArray("data");
for (JsonObject result : results.getValuesAs(JsonObject.class)){
System.out.print(result.getJsonObject("from").getString("name"));
System.out.print(": ");
System.out.println(result.getString("message", ""));
System.out.println("-----------");
}
}
I would like to know how to parse the following JSON using jackson library in java to construct the URI like http://api.statdns.com/google.com/cname
{
"status": {
"status": 200,
"msg": "SUCCESS"
},
"apicalls": [
{
"API": {
"method": "get",
"success": "200",
"baseURL": "http://api.statdns.com/",
"param1": "google.com/",
"param2": "cname",
"continue_on_fail": "1",
"add_header2": "'Accept', 'application/json'",
"add_header1": "'Content-Type', 'application/json'",
"client_id": "101"
},
"id": 1385
}
]
}
I have written bad code to parse the above json array. Following is the code i used,
public void parseJSON(String json) {
try{
JsonFactory factory = new JsonFactory();
JsonParser parser;
parser = factory.createJsonParser(json);
parser.setCodec(new ObjectMapper()); // to avoid IllegalStateException
JsonToken current;
current = parser.nextToken();
if (current != JsonToken.START_OBJECT) {
System.out.println("Error: root should be object: quiting.");
return;
}
while (parser.nextToken() != JsonToken.END_OBJECT) {
String fieldName = parser.getCurrentName();
// Move from field name to field value
current = parser.nextToken();
if (fieldName.equals("APIcalls")) {
JsonNode node = parser.readValueAsTree();
JsonNode currentJson = node.findValue("API");
System.out.println("Current JSON :: " + currentJson);
JsonNode url = currentJson.get("baseURL");
JsonNode param1 = currentJson.get("param1");
JsonNode param2 = currentJson.get("param2");
String baseURL = url.asText();
String params1 = param1.asText();
String params2 = param2.asText();
String uri = baseURL + params1 + params2;
System.out.println("URL :: " + uri);
initiateRESTCall(uri);
}
}
} catch (JsonParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Could anyone help me to know parsing the JSON using jackson? Help is highly appreciated.
If you are using jackson library, then you should go something like this:
I am using response from http://api.statdns.com/google.com/cname
public void parseJSON(String json) {
JSONObject parse = new JSONObject(data);
if(parse.get("question") instanceof JSONObject){
JSONObject questionJson = (JSONObject) parse.get("question");
System.out.println("Name"+questionJson.getString("name"));
System.out.println("Type"+questionJson.getString("type"));
System.out.println("Class"+questionJson.getString("class"));
}
else if(parse.get("question") instanceof JSONArray){
JSONArray questionJson = (JSONArray) parse.get("question");
String[] nameAttrib=new String[questionJson.length()];
String[] typeAttrib=new String[questionJson.length()];
String[] classAttrib=new String[questionJson.length()];
for(int i=0;i<questionJson.length();i++){
JSONObject questionJsonData=(JSONObject)questionJson.get(i);
nameAttrib[i]=questionJsonData.getString("name");
typeAttrib[i]=questionJsonData.getString("type");
classAttrib[i]=questionJsonData.getString("class");
System.out.println("Name: "+nameAttrib[i]);
System.out.println("Type: "+typeAttrib[i]);
System.out.println("Class: "+classAttrib[i]);
}
}
else if (parse.get("question").equals(null)){
System.out.println("question"+null);
}
}
Here I am doing for "question" only, similarly you can do other as well say "answer", "authority" in case url you have mentioned http://api.statdns.com/google.com/cname.
Hopefully it helps you with your problem..!!!!
If you are confident in the JSON not changing, a quick and dirty way to simplify your code is to use JSON Pointers.
// prefer injecting your project's ObjectMapper
private static final ObjectMapper om = new ObjectMapper();
public void parseJSON(String json) throws IOException {
JsonNode jsonNode = om.readTree(json);
String uri = new StringBuilder(jsonNode.findValue("baseURL").asText())
.append(jsonNode.findValue("param1").asText())
.append(jsonNode.findValue("param2").asText())
.toString();
initiateRESTCall(uri);
}
This becomes vulnerable if multiple apicalls entries are returned.
I don't know JACKSON library but I think it is similar to GSON. You just have to make some POJO and the library will take care of filling the fields for you.
For instance to convert your string to MyJSONClass use the following classes :
class Status {
int status;
String msg;
}
class APIClass {
String method;
String success;
String baseURL;
String param1;
String param2;
String continue_on_fail;
String add_header2;
String add_header1;
String client_id;
}
class APICall {
APIClass API;
int id;
}
class MyJSONClass {
Status status;
List<APICall> apicalls;
}
This set of classes could be transformed to JSON with JACKSON library (thanks to this stackoverflow answer) like that:
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(object);
I am new to stackoverflow.
I am creating an Java application which it will get data from a web server. The data is in json format. Example"
[
{
"item_name": "Adame",
"item_type": "Special",
"item": "Chestplate",
"item_min_lvl": "50",
"enchantment": {
"health": "0.3",
"dam": "24%",
"life": "0.1",
"xp": "24%",
"loot": "22%"
},
"def": "73"
},
{
"item_name": "Sticks'",
"item_type": "Unique",
"item": "Stick",
"item_min_lvl": "4",
"enchantment": {
"health": "0.6",
"mana": "1",
"dam": "12%",
"life": "0.3",
"xp": "17%",
"loot": "17%"
},
"min_dam": "39",
"max_dam": "34"
}
]
I know how to deserialize json using Gson. As you can see, it's started with [. I never deserialize this case before. Also, the json data is not the same(e.g. enchantment). I also searched in Google but I can't find any similar case. Can anyone help me with the code?
Try with this code. You will get the answer of your question. It's an List with 2 items.
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(new File("resources/json1.txt")));
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<MyJSON>>() {
}.getType();
List<MyJSON> list = gson.fromJson(builder.toString(), listType);
// you can try this form as well
// MyJSON[] list = gson.fromJson(builder.toString(), MyJSON[].class);
for (MyJSON json : list) {
System.out.println(json.toString());
}
...
class MyJSON {
String item_name;
String item_type;
String item;
String item_min_lvl;
Enchantment enchantment;
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("\nitem_name:").append(item_name);
builder.append("\nitem_type:").append(item_type);
builder.append("\nitem:").append(item);
builder.append("\nitem_min_lvl:").append(item_min_lvl);
builder.append("\n\nEnchantment Details:");
builder.append("\nhealth:").append(enchantment.health);
builder.append("\ndam:").append(enchantment.dam);
builder.append("\nlife:").append(enchantment.life);
builder.append("\nxp:").append(enchantment.xp);
builder.append("\nloot:").append(enchantment.loot);
return builder.toString();
}
}
class Enchantment {
String health;
String dam;
String life;
String xp;
String loot;
}
output:
item_name:Adame
item_type:Special
item:Chestplate
item_min_lvl:50
Enchantment Details:
health:0.3
dam:24%
life:0.1
xp:24%
loot:22%
item_name:Sticks'
item_type:Unique
item:Stick
item_min_lvl:4
Enchantment Details:
health:0.6
dam:12%
life:0.3
xp:17%
loot:17%
EDIT
The structure of each entry is not same hence you can't use POJO for this type of JSON.
Simply use ArrayList<Map<String, Object>> and access the value based on key from the map.
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<Map<String, Object>>>() {
}.getType();
ArrayList<Map<String, Object>> list = gson.fromJson(builder.toString(), listType);
for (Map<String, Object> json : list) {
for (String key : json.keySet()) {
System.out.println(key + ":" + json.get(key));
}
System.out.println("===========");
}
output:
item_name:Adame
item_type:Special
item:Chestplate
item_min_lvl:50
enchantment:{health=0.3, dam=24%, life=0.1, xp=24%, loot=22%}
def:73
===========
item_name:Sticks'
item_type:Unique
item:Stick
item_min_lvl:4
enchantment:{health=0.6, mana=1, dam=12%, life=0.3, xp=17%, loot=17%}
min_dam:39
max_dam:34
===========
This is actually valid in Java and with GSON:
YourObject[] locs = gson.fromJson (someJsonString, YourObject[].class);
It'll parse and return an array of YourObject. Just create Java Classes that represent your JSON objects, and replace the placeholders as necessary.
EDIT:
As Braj said before, you can create a fully formed POJO, including the other, (non-symmetrical) attributes (I'm borrowing the code from from Braj's answer here):
//... snip ...
class MyJSON
{
String item_name;
String item_type;
String item;
String item_min_lvl;
Enchantment enchantment;
// Heres the other attributes
String min_dam;
String max_dam;
}
//... snip ...
GSON will parse it and set the values to null if they aren't provided in the original JSON.
However, from the other question, it seems that the JSON (Java - JSON Parser Error) for enchantment is provided inconsistently, so this will cause issues. I would recommend sending JSON for enchantment as an array for consistency, then you could structure your POJO as:
//... snip ...
class MyJSON
{
String item_name;
String item_type;
String item;
String item_min_lvl;
Enchantment[] enchantment;
// Heres the other attributes
String min_dam;
String max_dam;
}
//... snip ...
I have a two POJO classes: AddressInformation and PackageInformation (with their getters and setters which are not specified in the below code).
public class AddressInformation {
private Integer address_id;
private String street_name;
private String city;
private String state;
private Integer zipcode;
}
public class PackageInformation {
private Integer packageId;
private Integer packageType;
private Double packageWeight;
private AddressInformation packageSource;
private AddressInformation packageDestination;
}
I am persisting the instances of the classes using hibernate, and trying to retrieve the contents of PackageInformation from the database using hibernate and return the contents as JSON format. I am not using any framework.
Session session = HibernateUtils.getSessionFactory().openSession();
List<PackageInformation> packagelist = null;
tx = session.beginTransaction();
packagelist = session.createQuery("FROM PackageInformation").list();
tx.commit();
session.close();
I wanted the packagelist which has the collection of PackageInformation to be converted to JSON.
The catch here is that PackageInformation object has AddressInformation embedded in to it.
I tried the below code to convert the collection of PackageInformation to JSON:
JSONArray json = new JSONArray();
Gson gson = new Gson();
try{
for(PackageInformation pack : packagelist){
JSONObject jsonObj = new JSONObject();
AddressInformation sourceAddress = pack.getPackageSource();
JsonElement sourceAddressJson = gson.toJsonTree(sourceAddress);
jsonObj.put("sourceAddress",sourceAddressJson);
AddressInformation destinationAddress = pack.getPackageDestination();
JsonElement destinationeAddressJson = gson.toJsonTree(destinationAddress);
jsonObj.put("destinationAddress",destinationeAddressJson);
jsonObj.put("package_id",pack.getPackageId());
jsonObj.put("package_type",pack.getPackageType());
jsonObj.put("package_weight",pack.getPackageWeight());
}
returnString = json.toString();
}catch(JSONException je){
returnString = je.toString();
}
return Response.status(200).entity(returnString).build();
But I do not get JSON with sourceAddress and destinationAddress details embedded as JSON. Instead I got black fields: the sourceAddress and destinationAddress details are missing as in the JSON below.
[
{
"sourceAddress": {},
"destinationAddress: {},
"package_id": 1,
"package_type": 1,
"package_weight": 500,
}
{
"sourceAddress": {},
"destinationAddress: {},
"package_id": 2,
"package_type": 5,
"package_weight": 700,
}
]
To answer straight to your question, I think that your AddressInformation fields are empty (not null, just empty objects) so you are missing some points into your hibernate calls.
However, you can try to serialize all your stuff in another way that is more simple and safe. You are using JsonElement and JsonObject that I consider "low level" respect to the services that Gson provides to you.
I want to use my example also to show you at the same time the effect of an empty object, so compare source to destination addresses in the final JSON. This is my proposal.
public class PackageInformation {
#SerializedName("package_id")
Integer packageId;
#SerializedName("package_type")
Integer packageType;
#SerializedName("package_weight")
Double packageWeight;
#SerializedName("sourceAddress")
AddressInformation packageSource;
#SerializedName("destinationAddress")
AddressInformation packageDestination;
}
As you can note, I added the #SerializedName annotation to change the name of serialized field (this is why, I think, you are using this approach). Then I use the simpliest serialization method the Gson provides you with.
public class Q19615935 {
public static void main(String[] args) {
List<PackageInformation> list = new ArrayList<PackageInformation>();
PackageInformation pi = new PackageInformation();
pi.packageId = 42;
pi.packageType = 21;
pi.packageWeight = 2000.0;
AddressInformation source = new AddressInformation();
source.address_id = 1;
source.city="A city";
source.state="A state";
source.street_name="A street name";
source.zipcode=0;
pi.packageSource= source;
pi.packageDestination=new AddressInformation();
list.add(pi);
Gson g = new Gson();
System.out.println(g.toJson(list));
}
}
Since I do not have your db, I built a list by hands and this is my result (I formatted the console result):
[
{
"package_id": 42,
"package_type": 21,
"package_weight": 2000,
"sourceAddress": {
"address_id": 1,
"street_name": "A street name",
"city": "A city",
"state": "A state",
"zipcode": 0
},
"destinationAddress": { }
}
]
My conclusions:
If source and destination are not empty objects, you should use my serialization code.
If they are empty, you should check how they come from db and once solved, check again point 1.
I need to take the values from a JSON array and display them. Below is the code I have used.
getresponse class will send a HTTP request to a PHP page and get the relevant JSON array and the public variable res will hold that returned JSON array.
public class JSONConverter {
public void convert(){
getresponse gr=new getresponse();
String json = gr.res;
Data data = new Gson().fromJson(json, Data.class);
System.out.println(data);
}
}
class Data {
private String city;
private int reserve_no;
public String getCity() { return city; }
public int getReserve_no() { return reserve_no; }
public void setTitle(String city) { this.city = city; }
public void setId(int reserve_no) { this.reserve_no = reserve_no; }
public String toString() {
return String.format(city);
}
}
getrespose class
public class getresponse {
public static String res;
public void counter() {
try {
URL url = new URL("http://taxi.net/fetchLatest.php");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String str;
while ((str =br.readLine()) != null) {
res=str;
}
conn.disconnect();
Below is an example of JSON array returned.
[{"reserve_no":"20","city":"city2","street":"street1234","discription":"discription123","date":"2012-10-22
04:47:54","customer":"abc"}]
This code doesn't display the city name of the JSON array returned. can someone help me with this by correcting the code or suggest a better or easier method if any? :)
Nikita already gave you the correct solution, but here it is, step by step.
I reduced your problem to this minimal test:
import com.google.gson.Gson;
public class TestGSON
{
public static void main( String[] args )
{
// that's your JSON sample
String json = "[{\"reserve_no\":\"20\",\"city\":\"city2\",\"street\":\"street1234\",\"discription\":\"discription123\",\"date\":\"2012-10-22 04:47:54\",\"customer\":\"abc\"}]";
// note: we tell Gson to expect an **array** of Data
Data data[] = new Gson().fromJson(json, Data[].class);
System.out.println(data[0]);
}
}
The problem is that your JSON fragment is actually an array of objects, not just an object (hence the [] around it). So, you need to tell GSon it must expect an array of Data, not just a Data object. By the way, the exception that's thrown when executing your code as-is already told you so:
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
unless of course it got swallowed by an empty catch block
With respect to the Data class: think twice before you override the toString method like you did here. I would drop that method and just do
System.out.println( data[0].getCity() );
Gson maps json string to your class basing on your class properties names. So Data class has property title which is supposed to be mapped to city in json array. You need to rename you property to city so Gson can figure out where to put city from json array.
Or you can use annotations to explicitly map city to title. Check this: https://sites.google.com/site/gson/gson-user-guide#TOC-JSON-Field-Naming-Support