Sorry, possible newbie question, I'm trying to learn Java while contributing to a project at work. Actually code is Groovy (& we're using Grails) but assume that's the same for this purpose.
I'm trying to convert a JDBC ResultSet to JSON (to send to the front end). Got the following code from a blog:
// Convert JDBC ResultSet to JSON string
public static JSONArray convertToJSON(ResultSet resultSet)
throws Exception {
JSONArray jsonArray = new JSONArray();
ResultSetMetaData metaData = resultSet.getMetaData(); // Result set meta data
int total_columns = metaData.getColumnCount(); // Number of columns in the row
while (resultSet.next()) { // Take each row from the result set
JSONObject obj = new JSONObject();
for (int i = 0; i < total_columns; i++) {
obj.put(metaData.getColumnLabel(i + 1)
.toLowerCase(), resultSet.getObject(i + 1));
}
jsonArray.put(obj);
}
return jsonArray.toString(); // Return as JSON string
}
This (I believe) will give me a JSON structure with the data in the root/top of the JSON. I want to move it into a sub-field (called e.g. 'data') and then have another couple of key/value pairs at root level. How would I modify the code to do this please? (I could pass the couple of extra values in as params)
Thanks.
You can do something like
JSONObject rootObject = new JsonObject();
rootObject.put("data", jsonArray);
This will let you treat your JSON like a key-value pair and should accomplish what you are asking.
Additionally, you may want to look at using an ObjectMapper to convert your object to JSON. This would allow you to create a JSONObject from a Java object with something like objectMapper.writeValueAsString(resultSet)
I think there is an error in the code snippet you provided, since your signature states JSONArray as a return type but you return a String, anyway here is what I would suggest:
public static JSONObject convertToJSON(ResultSet resultSet)
throws Exception {
JSONObject root = new JSONObject();
JSONArray jsonArray = new JSONArray();
root.put("data", jsonArray);
ResultSetMetaData metaData = resultSet.getMetaData(); // Result set meta data
int total_columns = metaData.getColumnCount(); // Number of columns in the row
while (resultSet.next()) { // Take each row from the result set
JSONObject obj = new JSONObject();
for (int i = 0; i < total_columns; i++) {
obj.put(metaData.getColumnLabel(i + 1)
.toLowerCase(), resultSet.getObject(i + 1));
}
jsonArray.put(obj);
}
return root;
}
As this is a Groovy question, you could make your code more Groovy ;-)
static String convertToJSON(ResultSet resultSet) throws Exception {
def metaData = resultSet.metaData // Result set meta data
def result = []
while (resultSet.next()) { // Take each row from the result set
result << (1..metaData.columnCount).collectEntries {
[metaData.getColumnLabel(it).toLowerCase(), resultSet.getObject(it)]
}
}
return new JsonBuilder(result).toString() // Return as JSON string
}
Related
I have following JSONObject (not array, which I don't mind to convert). I am trying to do two things:
get the count of genre entry as "poetry" (count = 2).
get the key value of author name and genre:
authorName = malcolm
genreName = newsarticle
authorName = keats
genreName = poetry
{ "AddressBook" :{
"Details" :{
"authorname" :{
"Author-malcolm":{
"genre" :"poetry"
}
"Author-keats":{
"genre" :"poetry"
}
}
}
}
}
Code which I tried:
public static void main(String[] args) throws Exception, IOException, ParseException {
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("My path to JSON"));
JSONObject jsonObject = (JSONObject) obj;
JSONArray arrayhere = new JSONArray();
arrayhere.add(obj);
System.out.println(arrayhere);
int count = 0;
for(int i = 0; i < arrayhere.size(); i++) {
JSONObject element = arrayhere.getJSONObject(i);//The method getJSONObject(int) is undefined for the type JSONArray
String branchName = element.getString("genre");//The method getString(String) is undefined for the type JSONObject
if(branchName.equals("poetry")) {
count ++;
}
}
System.out.println("Count f0r poetry genre=" + count);
}
}
I have looked at solutions all over. There is no question similar to this at stackoverflow. I am not sure if the procedure is correct.
A few problems here.
First, I'm not sure where you got that example JSON but you can't work with that. That's not even valid JSON Formatting.
Looks like you want something like this:
{
AddressBook:
[
{
authorname: "author-malcom",
genre:"poetry"
},
{
authorname: "author-keats",
genre: "poetry"
}
]
}
That's the structure you're trying to create in JSON.
So, you're parsing this in from a file into a JSONObject that has a key called AddressBook inside of it. That key points to an array of JSONObjects representing authors. Each of those objects will have a key called genre. You're trying to access the genre key and count on a condition.
What you did above was create attempt to create a JSONObject from an invalid string, and then add the entire JSONObject itself into the JSONArray. JSONArray.add() doesn't convert an object to an array, it literally adds it onto the array.
jsonObj => {"Name":"name1","Id":1000}
jsonArray.add(jsonObj)
jsonArray => [{"Name":"name1","Id":1000}]
That's what you did in your code above. You didn't create an array from a JSONObject, you added an object to the array.
Proper use is going to look like:
Object obj = parser.parse(new FileReader("path_to_file"));
JSONObject jobj = (JSONObject) obj;
//access key AddressBook
JSONArray author_array = jobj.getJSONArray("AddressBook");
int poetry = 0;
for(int i = 0; i < author_array.length(); i++) {
JSONObject author = (JSONObject) author_array.get(i);
if(author.getString("genre").equals("poetry")) {
poetry++;
}
}
To summarize, you're problems come from a lack of understanding about JSON Formatting and how to access elements within a JSON Object.
Paste in the sample JSONObject I gave you above here. That site will let you visualize what you're working with.
I am trying retrieving the following JSON data from imagga's image recognition API.
{"results":[{"image":"http://docs.imagga.com/static/images/docs/sample/japan-605234_1280.jpg","tagging_id":null,"tags":[{"confidence":63.346307851163395,"tag":"valley"},{"confidence":60.66263009377379,"tag":"mountain"},{"confidence":44.39096006516168,"tag":"canyon"},{"confidence":42.08210930346856,"tag":"landscape"},{"confidence":33.52198895357515,"tag":"geological formation"},{"confidence":32.702112467737216,"tag":"mountains"},{"confidence":28.626223994488203,"tag":"glacier"},{"confidence":28.36,"tag":"natural depression"},{"confidence":28.03481906795487,"tag":"ravine"},{"confidence":27.269738461024804,"tag":"sky"},{"confidence":26.130797131953397,"tag":"rock"},{"confidence":23.11898739400327,"tag":"travel"},{"confidence":21.75182989551758,"tag":"alp"},{"confidence":20.956625061326214,"tag":"national"},{"confidence":20.15360199670358,"tag":"park"},{"confidence":19.826365024393702,"tag":"stone"},{"confidence":19.717420656127437,"tag":"water"},{"confidence":18.049071926896588,"tag":"river"},{"confidence":17.81629840041474,"tag":"hill"},{"confidence":17.30594970410163,"tag":"tourism"},{"confidence":17.192663177192692,"tag":"clouds"},{"confidence":16.53588724897844,"tag":"scenic"},{"confidence":15.98967256769248,"tag":"peak"},{"confidence":15.792599629554461,"tag":"lake"},{"confidence":15.532788988165363,"tag":"scenery"},{"confidence":15.453814687301834,"tag":"snow"},{"confidence":15.232632664896412,"tag":"outdoors"},{"confidence":15.212304004139495,"tag":"range"},{"confidence":15.042325772263556,"tag":"hiking"},{"confidence":14.958759294889424,"tag":"tree"},{"confidence":14.78842712696222,"tag":"forest"},{"confidence":12.853490785491731,"tag":"grass"},{"confidence":12.242518977753525,"tag":"desert"},{"confidence":12.095999999999998,"tag":"natural elevation"},{"confidence":12.03899501602295,"tag":"america"},{"confidence":11.49381779097963,"tag":"environment"},{"confidence":11.250534926394025,"tag":"usa"},{"confidence":10.935999552280517,"tag":"panorama"},{"confidence":10.838870815021957,"tag":"trees"},{"confidence":10.77081532273937,"tag":"south"},{"confidence":10.385222667460749,"tag":"summer"},{"confidence":9.967993711501377,"tag":"cloud"},{"confidence":9.960797892906747,"tag":"wild"},{"confidence":9.840206836878211,"tag":"natural"},{"confidence":9.64736797817423,"tag":"geology"},{"confidence":9.622992778171428,"tag":"rocky"},{"confidence":9.5011692563878,"tag":"outdoor"},{"confidence":9.36921935993258,"tag":"wilderness"},{"confidence":9.360136841263397,"tag":"vacation"},{"confidence":9.295849004816608,"tag":"rocks"},{"confidence":9.200756690906687,"tag":"high"},{"confidence":9.098263071652019,"tag":"highland"},{"confidence":8.912795414022,"tag":"tourist"},{"confidence":8.871604649828521,"tag":"hike"},{"confidence":8.849249986309006,"tag":"landmark"},{"confidence":8.696713373486205,"tag":"cliff"},{"confidence":8.600291951670297,"tag":"scene"},{"confidence":8.535889495009538,"tag":"stream"},{"confidence":8.530021520404471,"tag":"sunny"},{"confidence":8.255077489679804,"tag":"altitude"},{"confidence":8.016191292928964,"tag":"trail"},{"confidence":7.9938748285500605,"tag":"autumn"},{"confidence":7.985278417869093,"tag":"california"},{"confidence":7.927492176055299,"tag":"spain"},{"confidence":7.774043777890904,"tag":"adventure"},{"confidence":7.560207874392119,"tag":"peaceful"},{"confidence":7.485827508554503,"tag":"fall"},{"confidence":7.283862421876644,"tag":"erosion"},{"confidence":7.272123549182718,"tag":"terrain"},{"confidence":7.24510515635207,"tag":"rural"},{"confidence":7.234934522337296,"tag":"vista"},{"confidence":7.092282542389207,"tag":"holiday"}]}]}
I am using http://www.java2s.com/Code/Jar/o/Downloadorgjson20130603jar.htm library.
My Java code is as follows:
String imageUrl = "http://docs.imagga.com/static/images/docs/sample/japan-605234_1280.jpg",
apiKey = "",
apiSecret = "";
// These code snippets use an open-source library. http://unirest.io/java
HttpResponse response = Unirest.get("https://api.imagga.com/v1/tagging")
.queryString("url", imageUrl)
.basicAuth(apiKey, apiSecret)
.header("Accept", "application/json")
.asJson();
String js = response.getBody().toString();
System.out.println(js.toString());
JSONObject jObject = new JSONObject(response.getBody()); // json
System.out.print("hello");
JSONObject data1 = jObject.getJSONObject("results"); // get data
System.out.print(data1); // object
String projectname = data1.getString("tags"); // get the name
// from data.
System.out.print(projectname);
I am getting the error that
Exception in thread "main" org.json.JSONException:
JSONObject["results"] not found.
What I want to get is the list of "tag" and "confidence".
try this
JSONArray data1 = jObject.getJSONArray("results");
Edited Answer
String js = response.getBody().toString();
System.out.println(js.toString());
JSONObject jObject = new JSONObject(js); // json
System.out.print("hello");
JSONArray data1 = jObject.getJSONArray("results");
for(int i = 0; i < data1.length; i++)
{
JSONObject jsonObject = data1.getJSONObject(i);
String projectn ame = jsonObject.getString("tagging_id");
System.out.print(projectname);
JSONArray tagArray = jsonObject.getJsonArray("tags");
for(int j = 0; j < tagArray.length; j++)
{
JSONObject tagObject = tagArray.getJSON(j);
System.out.println("Tag == " + tagObject.getString("tag"));
}
}
To make your life more easy I'd go to model the Objects as POJO's and let Jackson's Objectmapper do the magic.
See http://wiki.fasterxml.com/JacksonDataBinding
I suppose you should try jObject.getJSONArray("results") instead of jObject.getJSONObject("results").
There is also a good tool to convert json to java: http://json2java.azurewebsites.net/
If you use it, you will see:
...other code...
public class RootObject
{
private ArrayList<Result> results;
public ArrayList<Result> getResults() { return this.results; }
public void setResults(ArrayList<Result> results) { this.results = results; }
}
...other code...
And results is list here, so use getJSONArray instead of getJSONObject
If you look into your json results has an array in it and therefore you should use getJSONArray and not getJSONObject.
JSONArray data1 = jObject.getJSONArray("results");
This question already has answers here:
Most efficient conversion of ResultSet to JSON?
(14 answers)
Closed 3 years ago.
I am getting the Resultset from mySQL server, and want to send it as JSON back to the client..
the server is writen in Java EE..
I have been looking up a lot for this.. but nothing simple..
is that elementary process really has to be that hard?
or is there anything wrong in my understanding?
Use Jackson for JSON-processing. If you convert your results to a POJO simply make the POJO Jackson compatible (getters will be serialized automatically for instance or use #JsonProperty.
Example for converting a pojo to JSON:
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(somePojo);
If you do not convert your results to a POJO the JsonNode subclass called ObjectNode can be used.
Example:
public String convert(ResultSet rs) {
ObjectNode node = new ObjectMapper().createObjectNode();
node.put("fieldName", rs.getString("columnName"));
return node.toString(); // this is proper JSON
}
However, the most common and clean approach is to return a POJO from your function (whether it is an EJB or a REST service or similar) and then let the framework convert it to JSON for you (typically the framework uses Jackson). This means that your method simply returns some kind of model object that is Jackson compatible.
https://gist.github.com/mreynolds/603526
public String convertResultSetToJson(ResultSet resultSet) throws SQLException {
Joiner commaJoiner = Joiner.on(", \n");
StringBuilder builder = new StringBuilder();
builder.append("{ \"results\": [ ");
List<String> results = new ArrayList<String>();
while (resultSet.next()) {
List<String> resultBits = new ArrayList<String>();
ResultSetMetaData metaData = resultSet.getMetaData();
for (int i = 1; i <= metaData.getColumnCount(); i++) {
StringBuilder resultBit = new StringBuilder();
String columnName = metaData.getColumnName(i);
resultBit.append("\"").append(columnName).append("\": \"").append(resultSet.getString(i)).append("\"");
resultBits.add(resultBit.toString());
}
results.add(" { " + commaJoiner.join(resultBits) + " } ");
}
builder.append(commaJoiner.join(results));
builder.append("] }");
return builder.toString();
}
You may use JSONObject provided by org.json.
Import org.json.JSONObject into your file. Then you can convert the resultset as follows:
jsonObject = new JSONObject();
jsonObject.put(key,resultSet.getInt(resultSet.findColumn(columname)));
return jsonObject.toString();
So if you wanted to return a column with name NO_OF_DAYS having value 3 into a json object such as this {"days" : "3"}, you write the code as:
jsonObject.put("days",resultSet.getInt(resultSet.findColumn("NO_OF_DAYS")));
#SuppressWarnings("unchecked") //we use 3rd-party non-type-safe types...
public static String convertResultSetToJson(ResultSet resultSet) throws SQLException
{
JSONArray json = new JSONArray();
ResultSetMetaData metadata = resultSet.getMetaData();
int numColumns = metadata.getColumnCount();
while(resultSet.next()) //iterate rows
{
JSONObject obj = new JSONObject(); //extends HashMap
for (int i = 1; i <= numColumns; ++i) //iterate columns
{
String column_name = metadata.getColumnName(i);
obj.put(column_name, resultSet.getObject(column_name));
}
json.add(obj);
}
return json.toJSONString();
}
source: https://github.com/OhadR/ohadr.common/blob/master/src/main/java/com/ohadr/common/utils/JsonUtils.java
you can use easily: JsonUtils.convertResultSetToJson(...)
Grab the JAR from Maven Central,
<!-- https://mvnrepository.com/artifact/com.ohadr/ohadr.commons -->
<dependency>
<groupId>com.ohadr</groupId>
<artifactId>ohadr.commons</artifactId>
<version>0.3</version>
</dependency>
Trying to parse multi-level JSON in Java.
Having JSON input in format like this:
{"object1":["0","1", ..., "n"],
"objects2":{
"x1":{"name":"y1","type":"z1","values":[19,20,21,22,23,24]}
"x2":{"name":"y2","type":"z2","values":[19,20,21,22,23,24]}
"x3":{"name":"y3","type":"z1","values":[19,20,21,22,23,24]}
"x4":{"name":"y4","type":"z2","values":[19,20,21,22,23,24]}
}
and need to get all objects from 2 by one of the attributes, e.g. get all objects with type = z1.
Using org.json*.
Tried to do something like this:
JSONObject GeneralSettings = new JSONObject(sb.toString()); //receiving and converting JSON;
JSONObject GeneralObjects = GeneralSettings.getJSONObject("objects2");
JSONObject p2;
JSONArray ObjectsAll = new JSONArray();
ObjectsAll = GeneralObjects.toJSONArray(GeneralObjects.names());
for (int i=0; i < GeneralObjects.length(); i++){
p2 = ObjectsAll.getJSONObject(i);
switch (p2.getString("type")) {
case "z1": NewJSONArray1.put(p2); //JSON array that should contain values with type z1.
break;
case "z2": NewJSONArray2.put(p2); //JSON array that should contain values with type z2.
default: System.out.println("error");
break;
}
}
}
But getting null pointer exception and overall method seems not to be so well.
Please advise, is there any way to make it easier or, what am I doing wrong?
If you're getting a NullPointerException it's most likely that you haven't initialized NewJSONArray1 and NewJSONArray2.
You didn't include their declaration, but you probably just need to do
NewJSONArray1=new JSONArray();
NewJSONArray2=new JSONArray();
before your loop.
Aside: by convention java variables should start with a lower case letter, e.g. newJSONArray1
public static void main(String[] args) {
String s =
"{\"object1\":[\"0\",\"1\",\"n\"]," +
"\"objects2\":{" +
"\"x1\":{\"name\":\"y1\",\"type\":\"z1\",\"values\":[19,20,21,22,23,24]}," +
"\"x2\":{\"name\":\"y2\",\"type\":\"z2\",\"values\":[19,20,21,22,23,24]}," +
"\"x3\":{\"name\":\"y3\",\"type\":\"z1\",\"values\":[19,20,21,22,23,24]}," +
"\"x4\":{\"name\":\"y4\",\"type\":\"z2\",\"values\":[19,20,21,22,23,24]}" +
"}}";
System.out.println(s);
JSONObject json = new JSONObject(s);
JSONObject object2 = json.optJSONObject("objects2");
if (object2 == null) {
return;
}
JSONArray result = new JSONArray();
for (Object key : object2.keySet()) {
JSONObject object = object2.getJSONObject(key.toString());
String type = object.optString("type");
if ("z1".equals(type)) {
System.out.println(object.toString());
result.put(object);
}
}
System.out.println(result);
}
You can always convert it to string and use json-path:
https://code.google.com/p/json-path/
I'm going to parse a json array from web server to android app.The array looks like this
{"Level":
[
{"route":[{"lat":38.889762,"lgn":-77.081764},
{"lat":38.89096,"lgn":-77.081916}]},
{"route":[{"lat":38.889762,"lgn":-77.081764},
{"lat":38.89096,"lgn":-77.081916}]},
{"route":[{"lat":38.889762,"lgn":-77.081764},
{"lat":38.89096,"lgn":-77.081916}]}
]
}
my java code is
JSONObject json = new JSONObject(result);
JSONArray jArray = json.getJSONArray("Level");
rlevel = new ArrayList<LatLng>();
System.out.println("*****JARRAY*****"+jArray.length());
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
jlat = json_data.getDouble("lat");
jlgn = json_data.getDouble("lgn");}
but not works! any idea?after this i want to save each route into an array (etc $plan[1]=first route from json, $plan[2]=second route from json)
Try something like this:
//code is a String where you saved the json
JSonObject json= new JsonParser().parse(code).getAsJsonObject();
JsonArray jArray= json.getAsJsonArray("Level");
rLevel=new ArrayList<LatLng>();
//notice the use of the size() method. There is not length() method defined for ArrayList
System.out.println("*****JARRAY*****"+jArray.size());
for(int i=0;i<jArray.size();i++){
//notice that inside the Level Array you have route-arrays
JSonObject level_item = jArray.get(i).getAsJsonObject();
JSonArray route= level_item.getAsJSonArray("route");
//now I don't know exactly what data you want to extract, since there are 2
//pairs of LatLng, for the first one:
jlat = route.get(0).get("lat").getAsDouble();
jlgn= route.get(0).get("lgn").getASDouble();
The exact names for methods and JsonObjects tend to differ from a library to another, but the principle is the same.
This parse task can be done very easily using droidQuery:
try {
JSONObject json = $.parseJSON(result);
if (json.has("Level")) {
Object[] datas = $.makeArray(json.getJSONArray("Level"));
for (Object data : datas) {
JSONObject obj = (JSONObject) data;
Object[] coordinates = $.makeArray(obj.getJSONArray("route"));
for (Object coord : coordinates) {
Map<String, ?> map = $.map((JSONObject) coord);
double latitude = (Double) map.get("lat");
double longitude = (Double) map.get("lgn");
//TODO: do something with these values
}
}
}
else {
Log.d("JSON", "Result does not contain 'Levels' variable");
}
}
catch (Throwable t) {
t.printStackTrace();
}