Jersey RESTful: How to populate DAO with a local json file? - java

this is my first time building a Jersey Restful web service.
The project is supposed to be a server that provides information about Reddit posts. For now, this information is stored in a large JSON file, and because it is not supposed to be manipulated, my idea is to store this information in the dao class in form of Post instances.
here is my projects' folder organisation: filesView
So my idea is to populate the dao class by reading the json file something like this:
public enum PostDao {
instance;
private Map<String, Post> posts = new HashMap<String, Post>();
private PostDao() {
//JSON parser object to parse read file
System.out.println("init");
JSONParser jsonParser = new JSONParser();
try {
FileReader reader = new FileReader("src/main/resources/data/posts.json");
//Read JSON file
Object obj = jsonParser.parse(reader);
JSONArray postsArr = (JSONArray) obj;
for (Object p : postsArr) {
JSONObject post = (JSONObject) p;
Post pobj = new Post(post.get("title"), post.get("author"));
posts.put(pobj.getId(), pobj);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
public Map<String, Post> getModel() {
return posts;
}
The problem is that I do not know where to put the json file and what the path would be.
Is there a standard folder and path to store this kind of files? Or is there a different way to populate the dao class?

I managed to find a solution which was pretty simple:
JSONParser jsonParser = new JSONParser();
try {
//get JSON file's path
InputStream in = this.getClass().getResourceAsStream("/data/posts.json");
BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
//Read JSON file
Object obj = jsonParser.parse(br.readLine());
for (Object p : (JSONArray) obj) {
JSONObject post = (JSONObject) p;
//add post to mapping
this.addPost(new Post(generateId(),
(String)post.get("user"),
(String)post.get("title"),
(String)post.get("date")));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
Note: my json file consisted of only one line (as text file) so that is why BufferedReader.readLine() was enough

Related

How can I read and write from and to a JSON file?

So I tried to write some code using what I found out on different sites but nothing works. Every time I try to write in to the file it doesn't work.
Here is the code for writing and reading from and in a JSON file:
HashMap<Word, ArrayList<Word>> map=null;
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("Dictionar.json"));
JSONObject jsonObject = (JSONObject) obj;
map=(HashMap) jsonObject;
} catch (Exception e) {
e.printStackTrace();
}
Dictionar dictionar=new Dictionar();
dictionar.setDictionar(map);
Here is the code for writing to the file:
JSONObject obj = new JSONObject();
obj.putAll(dictionar);
File f=new File("Dictionar.json");
f.createNewFile();
FileWriter file = new FileWriter(f);
obj.writeJSONString(file);
System.out.println("Successfully Copied JSON Object to File...");
System.out.println("\nJSON Object: " + obj);
}
catch (IOException i) {
i.printStackTrace();
}
The variable dictionar is a HashMap.

Is there a way to parse JSON with java? [duplicate]

This question already has answers here:
Converting JSON data to Java object
(14 answers)
Closed 6 years ago.
Here is what I have so far:
public Bitmap getAlbumCover(Context context, String song, String artist) {
this.context = context;
song = song.replace(" ", "%20");
artist = artist.replace(" ", "%20");
try {
conn = new URL("https://api.spotify.com/v1/search?q=track" + song + ":%20artist:" + artist + "&type=track)").openConnection();
} catch (IOException e) {
e.printStackTrace();
}
if (conn != null)
conn.setDoOutput(true);
try {
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
if (reader != null) {
// Read Server Response
String line2 = null;
try {
while ((line2 = reader.readLine()) != null) {
sb.append(line2);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
json = new JSONArray(sb.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
JSONParser parser= new JSONParser();
try {
JSONObject jsonObject = (JSONObject) parser.parse(reader);
try {
array = (JSONArray) jsonObject.get("items");
} catch (JSONException e) {
e.printStackTrace();
}
// take each value from the json array separately
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
The JSON I am using is located here:
https://api.spotify.com/v1/search?q=track:Ready%20To%20Fall%20artist:rise%20against%20&type=track
I am trying to get the image url located in the images array and the preview_track url located in items.
I use Jackson library to parse JSON to java opbject.
if you create your java object with the same structure as JSON this can be done using this:
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(jsonUrl, YourClass.class);
So your OBJECT will have tracks and then tracks will have object album and album will have object other details. Just structure it as the JSON is and you are there.

Parsing Multiple JSON Strings to Objects using json-simple

I have a socket server running, which will emit json strings for clients. I tried to use json-simple for parsing them. But, the problem I face is that, the server doesn't have any delimiter character to segregate json strings. So, my json-simple JSONParser throws ParseException.
As an alternate, I tried to use json-smart. But, in this case, the JSONParser returns only the first object and ignores rest of the string.
I'm new to this json parsing stuff. It would be great if people can direct me to correct way of handling json string streams.
Edit: - Adding JSON String and Sample Code
{"type":"response","id":"1","result":[true,0]}{"type":"response","id":"2","result":[true,1]}
Currently this method returns the single object when I use json-smart and null when json-simple is used.
public JSONObject getResponse(JSONObject request) {
String s = null;
Socket soc = null;
PrintWriter sout = null;
BufferedReader sin = null;
try {
soc = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
sout = new PrintWriter(soc.getOutputStream());
sin = new BufferedReader(
new InputStreamReader(soc.getInputStream()));
sout.println(request.toJSONString());
sout.flush();
s = sin.readLine();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
sin.close();
sout.close();
soc.close();
} catch (Exception e) {
}
}
Object response = null;
try {
response = JSONValue.parseWithException(s.toString());
}catch (ParseException e){
e.printStackTrace();
}
return (JSONObject) response;
Thanks in advance,
Kaja
I have found a solution using Jackson. Here is the code that worked for me.
MappingJsonFactory factory = new MappingJsonFactory();
JsonParser parser = factory.createParser(soc.getInputStream());
JsonToken curToken = parser.nextToken();
if (curToken != JsonToken.START_OBJECT) {
System.err.println("Not in start object!, Exiting...");
return null;
}
while (runParser.get() == true) {
if (curToken == JsonToken.START_OBJECT) {
TreeNode node = parser.readValueAsTree();
System.out.println(node.getClass().getName());
System.out.println(node);
}
curToken = parser.nextToken();
}
Thanks Kaja Mohideen! It's working with a small change in while loop.
This code works perfectly. In my case input json is in file.
libs used : jackson-core, jackson-annotation and jackson-databind
MappingJsonFactory factory = new MappingJsonFactory();
JsonParser parser = null;
File file = new File("jsontest.txt");
try {
parser = factory.createParser(file);
JsonToken curToken = parser.nextToken();
if (curToken != JsonToken.START_OBJECT) {
System.err.println("Not in start object!, Exiting...");
}
while (parser.hasCurrentToken()) {
if (curToken == JsonToken.START_OBJECT) {
TreeNode node = parser.readValueAsTree();
System.out.println(node);
}
curToken = parser.nextToken();
}
} catch (JsonParseException e) {
e.printStackTrace();
}

Access JSON object in java

I need to update a value in my JSON file using java but somehow I am unable to.Following is my JSON format which I am trying to parse
{
"recentActivities":[
{
"displayValue":"POC | Augmented Reality",
"link":"poc.jsp?search=augmented%20reality",
"timestamp":"18/07/2013 17:33"
},
{
"displayValue":"POC | Image Editing in Hybrid Application",
"link":"poc.jsp?search=image%20editing",
"timestamp":"18/07/2013 01:00"
}
],
"lastEmailSent": "29/06/2013 00:00"
}
I need to update lastEmailSent to current date but somehow I am getting stuck. Below is my java code which i am using
private void updateLastEmailTimeStamp(String jsonFilePath) {
JSONParser parser = new JSONParser();
JSONObject jsonObject = new JSONObject();
JSONObject lastEmailTimeStamp = new JSONObject();
FileReader reader =null;
try {
File jsonFile = new File(jsonFilePath);
reader = new FileReader(jsonFile);
jsonObject = (JSONObject) parser.parse(reader);
lastEmailTimeStamp = (JSONObject) jsonObject.get("lastEmailSent");
//write current date as last mail sent time.
writeTimeStamp(lastEmailTimeStamp, jsonFile);
APP_LOGGER.info("last Email Sent timestamp updated");
} catch (IOException ex) {
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
} catch (ParseException ex) {
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
}
}
private void writeTimeStamp(JSONObject lastEmailTimeStamp, File jsonFile) {
FileWriter writer = null;
try{
writer = new FileWriter(jsonFile);
String currentDate = MyDateFormatterUtility.formatDate(new Date(),"dd/MM/yyyy HH:mm");
lastEmailTimeStamp.put(SubscriptionConstants.LAST_EMAIL_TIMESTAMP, currentDate);
writer.write(lastEmailTimeStamp.toJSONString());
}catch(IOException ex){
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
}finally{
try {
writer.flush();
writer.close();
} catch (IOException ex) {
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
}
}
}
I am getting error in the following line
lastEmailTimeStamp = (JSONObject) jsonObject.get("lastEmailSent");.
I guess I am not correctly parsing or accessing the object. Can somebody please make me correct?
Thank you!
I agree with #Hot Licks, but you can try fixing it by doing:
String lastEmailSent = jsonObject.getString("lastEmailSent");
Also, if that isn't the problem, it may be that the text coming from your file is not exactly the JSON text you posted here. In which case, you can read the file into a string, add a breakpoint and check the string to see if it has all the JSON elements you expect it to.
In Java 7 you can read the text in like:
String content = readFile(jsonFilePath, Charset.defaultCharset());
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return encoding.decode(ByteBuffer.wrap(encoded)).toString();
}
Finally, i was able to figure out the solution. Following changes were needed in the code
private void updateLastEmailTimeStamp(String jsonFilePath) {
JSONParser parser = new JSONParser();
JSONObject jsonObject = new JSONObject();
FileReader reader =null;
try {
File jsonFile = new File(jsonFilePath);
reader = new FileReader(jsonFile);
jsonObject = (JSONObject) parser.parse(reader);
jsonObject.remove("lastEmailSent");
//write current date as last mail sent time.
writeTimeStamp(jsonObject, jsonFile);
APP_LOGGER.info("last Email Sent timestamp updated");
} catch (IOException ex) {
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
} catch (ParseException ex) {
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
} catch (RuntimeException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* Method to write current date as last mail sent timestamp
* denoting when the newsletter was sent last.
*
* #param jsonObj- date for last email sent.
* #param jsonFile - recentactivities.json file
*/
#SuppressWarnings("unchecked")
private void writeTimeStamp(JSONObject jsonObj, File jsonFile) {
FileWriter writer = null;
try {
writer = new FileWriter(jsonFile);
String currentDate = MyDateFormatter.formatDate(new Date(),"dd/MM/yyyy HH:mm");
jsonObj.put("lastEmailSent", currentDate);
writer.write(jsonObj.toJSONString());
}catch(IOException ex){
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
}finally{
try {
writer.flush();
writer.close();
} catch (IOException ex) {
APP_LOGGER.error(ex.getLocalizedMessage(), ex);
}
}
}

How do I use Google's Gson to get a certain value from a JSON response?

I am currently trying to parse through a the front page of Reddit using their cool website feature in which you can add /.json to any site to get the json of the page. So the url I am using is www.reddit.com/.json.
I want to get the subreddit of the first post by parsing through their json. How would I do this? I did some research and found the google gson api but I have no idea how to use it and their documentation does not really help me.
Here is my code so far, I have the Json in a string:
import java.io.*;
import java.net.*;
import com.google.gson.*;
public class Subreddits {
public static void main(String[] args) {
URL u = null;
try {
u = new URL("http://www.reddit.com/.json");
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection yc = null;
try {
yc = u.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
String inputLine = null;
StringBuilder sb = new StringBuilder();
try {
while ((inputLine = in.readLine()) != null){
sb.append(inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
inputLine = sb.toString();//String of json
System.out.println(inputLine);
//I want to get [data][children][data][subreddit]
}
}
You can create this class structure to parse your response (in pseudo-code):
class Response
Data data
class Data
List<Child> children
class Child
OtherData data
class OtherData
String subreddit
Then you parse your JSON string with:
Gson gson = new Gson();
Response response = gson.fromJson(inputLine, Response.class);
And in order to get the concrete data you need, just:
String subreddit = response.getData().getChildren().getOtherData().getSubreddit();
Note that you can change the names of the classes, but NOT the names of the attributes, since they have to match the names in the JSON response!
Also note that I have only added the attributes you need to get that concrete data, but if you add more attributes in the classes, matching the element names in the JSON, more data will be parsed...
Further similar examples here, here or here.
Finally note that you can make your classes nested to keep your project cleaner, but if however you don't like to write so many classes, and you are sure that you only want that specific value and you won't want any value else in the future, you can use this different approach, although I don't recommend it...

Categories

Resources