How to fetch JSON of desired format from MySQL - java

Using play framework 2.0 and here goes my java code :
String queryString="SELECT watchDuration, date(startTime) from SEData";
Query query=JPA.em().createNativeQuery(queryString);
List<Object[]> resultHours = (List<Object[]>) query.getResultList();
Gson gson = new Gson();
String json = gson.toJson(resultHours);
renderJSON(json);
After browsing for a while, I did try to use Gson, which resulted me with the following output :
[[5.0,"Feb 5, 2014"],[6.0,"Feb 6, 2014"],[1.0,"Feb 7, 2014"],[2.0,"May 3, 2017"],[3.0,"May 4, 2017"]]
Since I'm fetching this data to plot on a c3.js graph, I need it in the following format :
json:[{"value":5, "date":"Feb 5, 2014"},{"value":6, "date":"Feb 6, 2014"},{"value":1, "date":"Feb 7, 2014"},{"value":2, "date":"May 3, 2017"},{"value":3, "date":"May 4, 2017"}]
OR
json: {
value:[5, 6, 1, 2, 3],
date: ["Feb 5, 2014", "Feb 6, 2014", "Feb 7, 2014", "May 3, 2017", "May 4, 2017"]
}
How can I achieve the above format retrieved MySQL database?
I doubt if my approach towards Gson is wrong, because the output that I got is not even a JSON I believe. Guide me towards the right approach if I'm not moving towards one.
Thanks.

The problem is gson doesn't know what the properties are called, so it makes an array of unnamed values.
While adding a new class will simplify things, a new class for every return type of a query means a lot of rather useless classes, especially if they are only used for marshalling.
Instead, you can map a name to each list of properties like so
HashMap<String, ArrayList<Object> > map = new HashMap<String, ArrayList<Object> >();
ArrayList<Object> values = new ArrayList<Object>();
ArrayList<Object> dates = new ArrayList<Object>();
for(int i=0; i < list.size(); i++){
values.add(resultHours.get(i)[0]);
dates.add(resultHours.get(i)[1]);
}
map.put("value", values);
map.put("date", dates);
This produces the desired output:
{
"date": ["Jan","Feb","Mar","April"],
"value": [1,2,3,4]
}

Rather than returning a list of Object[] create an object which is typed
public class ResultHours {
public int value;
public Date date;
}
and then update the getResultList();
List<ResultHours[]> resultHours = (List<ResultHours[]>) query.getResultList();
I've not tested this but in theory it should work!

Related

Can't deserialize JSON array into class org

I want to make a string from json into an object of my class. The problem is, in the class I use an ArrayList and that's why (I think) I get the error message "Can't deserialize JSON array into class". How exactly can I separate the array and convert it into an ArrayList?
#POST
public Response createMocktail(String m){
MocktailDto mocktail = jsonb.fromJson(m, MocktailDto.class);
return Response.ok(mocktailManager.createMocktail(mocktail)).build();
}
Json String:
[
{
"id": 3,
"name": "Mojito",
"zutaten": [
{
"anzahl": 1,
"id": 5,
"name": "Rum"
},
{
"anzahl": 1,
"id": 6,
"name": "GingerAle"
}
]
}
]
JSONObject jsonObj = new JSONObject(m); does not work, it says constructor is undefined although I saw a few solutions like this
The problem is your input string is Array (when it starts with [)
There are a few possible solutions:
First:
MocktailDto[] data = jsonb.fromJson(m, MocktailDto[].class);
data[0];
Second:
Type listType = new TypeToken<ArrayList<MocktailDto>>(){}.getType();
ArrayList<MocktailDto> data = jsonb.fromJson(m, listType);
data.get(0);

How to remove curly braces before writing JSON object in java

I am trying to make a simple JSON-DB in Java since the current library on maven is horrendously overcomplicated. I have this method that takes in a key and value to put into a JSONObject and write it to my database.json file.
public static void put(String path, String key, Object[] value){
//creates new JSONObject where data will be stored
JSONObject jsondb = new JSONObject();
try{
//adds key and value to JSONObject
jsondb.put(key, value);
} catch (JSONException e){
e.printStackTrace();
} //end try-catch
try(PrintWriter out = new PrintWriter(new FileWriter(path, true))) {
out.write(jsondb.toString());
out.write(',');
} catch (Exception e){
e.printStackTrace();
} //end try-catch
} //end put()
Here is my main method where I write some data to the file
public static void main(String[] args) throws Exception {
String path = "app.json";
Object[] amogus = {"Hello", 1, 2, 3, 4, 5};
Object[] amogus1 = {"Hello", 1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
JsonDB db = new JsonDB(path);
db.put(path, "arr", amogus);
db.put(path, "arr1", amogus1);
}
What happens is that it save each data in a set of curly braces. So when I write to the file more than once like I do in my main method it saves it like this:
{"arr": ["Hello", 1, 2, 3, 4, 5]}{"arr1": ["Hello", 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]}
This causes VSCode to throw an error since this isnt valid JSON. How would I make the method remove the curly braces and add commas to make the above JSON valid JSON? I cant seem to find the documentation for this library (The library is org.json on maven).
This is a syntax issue. Your json is not valid because the json syntax want your data to be between curly braces like this:
{
"arr": ["Hello", 1, 2, 3, 4, 5],
"arr1": ["Hello", 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
}
instead of this, which is not a valid json:
{"arr": ["Hello", 1, 2, 3, 4, 5]}
{"arr1": ["Hello", 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]}
Create your data in your map object and let your json library convert (serialize) your object in a valid json.
I solved this problem by reading all of the content in the file and appending the JSON object that I wanted to write to the file and then write it all at once.

convert hashMap to JSON response java

I am using JAVA 7.
From HashMap>> data = new HashMap<>(); i am getting below Output
Here map contains dynamic records for days.
Here in array, first value is category1, second value is category2, third value is category3, fourth value is category4 .
{
11/20/17={
producer1=[
]
},
01/01/18={
producer1=[
1, //category1
1, //category2
1, //category3
1 //category4
],
producer2=[
5,
1,
9,
1
]
},
01/08/18={
producer2=[
1,
6,
1,
3
],
}
}
I want to produce output like below for all categories
{producerType : producer1
category1Data : [ 0,1,0]}, // 11/20/17 = 0,01/01/18 = 1,01/08/18 = 0 for category 1.
{producerType : producer2
category1Data : [ 0,5,1]},
Using Jackson API
ObjectMapper mapperObj = new ObjectMapper();
convert map to JSON String like
String jsonResp = mapperObj.writeValueAsString(hashMap);

how to parse JSON file with GSON

I have a very simple JSON with reviews for products, like:
{
"reviewerID": "A2XVJBSRI3SWDI",
"asin": "0000031887",
"reviewerName": "abigail",
"helpful": [0, 0],
"unixReviewTime": 1383523200,
"reviewText": "Perfect red tutu for the price. ",
"overall": 5.0,
"reviewTime": "11 4, 2013", "summary": "Nice tutu"
}
{
"reviewerID": "A2G0LNLN79Q6HR",
"asin": "0000031887",
"reviewerName": "aj_18 \"Aj_18\"",
"helpful": [1, 1],
"unixReviewTime": 1337990400,
"reviewText": "This was a really cute",
"overall": 4.0,
"reviewTime": "05 26, 2012",
"summary": "Really Cute but rather short."
}
I'd like to read it into my Java app using GSON. I have built a class to hold results for each review:
public class Review {
private String reviewerID;
private String asin;
private String reviewerName;
private ArrayList<Integer> helpful;
private String reviewText;
private Double overall;
private String summary;
private Long unixReviewTime;
private String reviewTime;
public Review() {
this.helpful = Lists.newArrayList();
}
// some getters and setters...
To read the JSON file, my code is:
Gson gson = new Gson();
JsonReader reader = new JsonReader(new FileReader(filename));
Review data = gson.fromJson(reader, Review.class);
data.toScreen(); // prints to screen some values
With this code, I can only retrieve the first review in the JSON, so my question is: how to iterate through all the reader and get the next reviews? I don't need to store the reviews in a List, just need to access the object once. Any help more than welcome.
You have to fetch the whole data in the list and then do the iteration as it is a file and will become inefficient otherwise.
private static final Type REVIEW_TYPE = new TypeToken<List<Review>>() {
}.getType();
Gson gson = new Gson();
JsonReader reader = new JsonReader(new FileReader(filename));
List<Review> data = gson.fromJson(reader, REVIEW_TYPE); // contains the whole reviews list
data.toScreen(); // prints to screen some values
just parse as an array:
Review[] reviews = new Gson().fromJson(jsonString, Review[].class);
then if you need you can also create a list in this way:
List<Review> asList = Arrays.asList(reviews);
P.S. your json string should be look like this:
[
{
"reviewerID": "A2SUAM1J3GNN3B1",
"asin": "0000013714",
"reviewerName": "J. McDonald",
"helpful": [2, 3],
"reviewText": "I bought this for my husband who plays the piano.",
"overall": 5.0,
"summary": "Heavenly Highway Hymns",
"unixReviewTime": 1252800000,
"reviewTime": "09 13, 2009"
},
{
"reviewerID": "A2SUAM1J3GNN3B2",
"asin": "0000013714",
"reviewerName": "J. McDonald",
"helpful": [2, 3],
"reviewText": "I bought this for my husband who plays the piano.",
"overall": 5.0,
"summary": "Heavenly Highway Hymns",
"unixReviewTime": 1252800000,
"reviewTime": "09 13, 2009"
},
[...]
]
In case you need to parse it from a file, I find the best solution to use a HashMap<String, String> to use it inside your java code for better manipultion.
Try out this code:
public HashMap<String, String> myMethodName() throws FileNotFoundException
{
String path = "absolute path to your file";
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
Gson gson = new Gson();
HashMap<String, String> json = gson.fromJson(bufferedReader, HashMap.class);
return json;
}

Parsing generic tag in JSON from GSON

I have a JSON which contains generic values. I tried it by using Maps but couldn't get the results. My problem is the generic tags starts from second level. Here is the JSON I am trying to parse through gson.
{
"success": true,
"status": 200,
"events": {
"Sep 2013": [
{
"artist_id": 1,
"created_at": "2013-05-18T15:21:00Z",
"duration": 2,
"end_time": "2013-09-19T22:00:00Z",
"event_desc": "",
"event_facebook_link": "",
"event_link": "https://www.smtickets.com/marketing/view/1316",
"feature_small": false,
"featured_status": false,
"id": 90,
In this JSON tag after "events" is generic i.e., "Sep 2013".
What I am trying right now is:
public Event event ;
public class Event {
public ArrayList<Map<String, String>> dates;
}
And I'm accessing it:
obj = gson.fromJson(reader, AllShowsActivityData.class);
Can anyone tell me that how can I make a class of dates. So Gson can serialize it. Or is there any other way to iterate first level tag and then I can declare it something like this
Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);
You can indeed use a Map, but you're not using it correctly. Note that what you have is a field "events", which is an object that contains a number of pairs string and array of objects:
{ "events": { "Sep 2013": [ {}, {}, ... ], ... } }
To parse your JSON you'd need a class structure like this (in pseudo-code):
class AllShowsActivityData
Map<String, List<Event>> events
class Event
int artist_id
String created_at //parsing as String to simplify...
int duration
...
And then your code to parse:
AllShowsActivityData obj = gson.fromJson(reader, AllShowsActivityData.class);
And finally, if what you want is to access the dates, you'll have all of them in:
Set<String> dates = obj.getEvents().keySet(); //"Sep 2013", ...
Note: in fact, if you only want those dates, you don't even need the class Event and you could use just Map<String, List<Object>> events...

Categories