In my web application I succeed in displaying data in html table using mybatis. Now I want to save the records of the Mysql table in a json file and create an array of users, I used Gson, the problem is that just one record saved in the file. Thanks.
Here the result in file.json:
{"data":
[
{"id":2,"Name":"Mike"}
]
}
servlet.java
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
for (User u : users) {
Gson gson = new Gson();
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
session.close();
You write all the users in same file C:\\file.json so just the last iteration of the loop saved.
You can convert the object List<User> into json and write it once (no needed loop)
Example:
try (Writer writer = new FileWriter("Output.json")) {
Gson gson = new GsonBuilder().create();
gson.toJson(users, writer);
}
I was previously using outputStream.writeObject and Serializable with default writer/reader for saving object data. Because of problems with code sustainability I have been after something else. This is the result. That BufferedWriter is mandatory, otherwise write speed drops 8 times. Notice that UTF-8 declaration which is default encoding of Json. Not sure whether not declaring it is safe.
Example:
private void saveJson(Object object, Type type, String directory, String fileName) {
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
OutputStream outputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
outputStream = new FileOutputStream(file);
BufferedWriter bufferedWriter;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,
StandardCharsets.UTF_8));
} else {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
}
gson.toJson(object, type, bufferedWriter);
bufferedWriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, IOException e: '" + e + "'");
} finally {
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(saveJson, "saveUserData, finally, e: '" + e + "'");
}
}
}
}
private Object loadJson(Type type, String directory, String fileName) {
Object jsonData = null;
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
InputStream inputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
inputStream = new FileInputStream(file);
InputStreamReader streamReader;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
streamReader = new InputStreamReader(inputStream,
StandardCharsets.UTF_8);
} else {
streamReader = new InputStreamReader(inputStream, "UTF-8");
}
jsonData = gson.fromJson(streamReader, type);
streamReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, IOException e: '" + e + "'");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(TAG, "loadJson, finally, e: '" + e + "'");
}
}
}
return jsonData;
}
where Type for example:
Type type = new TypeToken<Map<String, Object>>() { }.getType();
Quick fix to your code:
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
for (User u : users) {
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
However, in the case that your User class looks like this:
public class User {
String id;
String name;
}
Then you don't need to code the adapter as Gson is able to automatically generate the JSON code for a class that only has primitives (ints, Strings, etc.). So your code would look as #roy-shmuli but only if you omit the data and keep only the array as List can be completely generated without an adapter. The JSON code generated would look like this:
[
{"id":1, "name": "Mike"},
{"id":2, "name": "Lucy"}
]
Hope it helps to the beginners.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have this JSON string hardcoded in my code.
String json = "{\n" +
" \"id\": 1,\n" +
" \"name\": \"Headphones\",\n" +
" \"price\": 1250.0,\n" +
" \"tags\": [\"home\", \"green\"]\n" +
"}\n"
;
I want to move this to resources folder and read it from there,
How can I do that in JAVA?
This - in my experience - is the most reliable pattern to read files from class path.[1]
Thread.currentThread().getContextClassLoader().getResourceAsStream("YourJsonFile")
It gives you an InputStream [2] which can be passed to most JSON Libraries.[3]
try(InputStream in=Thread.currentThread().getContextClassLoader().getResourceAsStream("YourJsonFile")){
//pass InputStream to JSON-Library, e.g. using Jackson
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readValue(in, JsonNode.class);
String jsonString = mapper.writeValueAsString(jsonNode);
System.out.println(jsonString);
}
catch(Exception e){
throw new RuntimeException(e);
}
[1] Different ways of loading a file as an InputStream
[2] Try With Resources vs Try-Catch
[3] https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
Move json to a file someName.json in resources folder.
{
id: 1,
name: "Headphones",
price: 1250.0,
tags: [
"home",
"green"
]
}
Read the json file like
File file = new File(
this.getClass().getClassLoader().getResource("someName.json").getFile()
);
Further you can use file object however you want to use. you can convert to a json object using your favourite json library.
For eg. using Jackson you can do
ObjectMapper mapper = new ObjectMapper();
SomeClass someClassObj = mapper.readValue(file, SomeClass.class);
There are many possible ways of doing this:
Read the file completely (only suitable for smaller files)
public static String readFileFromResources(String filename) throws URISyntaxException, IOException {
URL resource = YourClass.class.getClassLoader().getResource(filename);
byte[] bytes = Files.readAllBytes(Paths.get(resource.toURI()));
return new String(bytes);
}
Read in the file line by line (also suitable for larger files)
private static String readFileFromResources(String fileName) throws IOException {
URL resource = YourClass.class.getClassLoader().getResource(fileName);
if (resource == null)
throw new IllegalArgumentException("file is not found!");
StringBuilder fileContent = new StringBuilder();
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(new File(resource.getFile())));
String line;
while ((line = bufferedReader.readLine()) != null) {
fileContent.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return fileContent.toString();
}
The most comfortable way is to use apache-commons.io
private static String readFileFromResources(String fileName) throws IOException {
return IOUtils.resourceToString(fileName, StandardCharsets.UTF_8);
}
Pass your file-path with from resources:
Example: If your resources -> folder_1 -> filename.json Then pass in
String json = getResource("folder_1/filename.json");
public String getResource(String resource) {
StringBuilder json = new StringBuilder();
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream(resource)),
StandardCharsets.UTF_8));
String str;
while ((str = in.readLine()) != null)
json.append(str);
in.close();
} catch (IOException e) {
throw new RuntimeException("Caught exception reading resource " + resource, e);
}
return json.toString();
}
There is JSON.simple is lightweight JSON processing library which can be used to read JSON or write JSON file.Try below code
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try (Reader reader = new FileReader("test.json")) {
JSONObject jsonObject = (JSONObject) parser.parse(reader);
System.out.println(jsonObject);
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
try(InputStream inputStream =Thread.currentThread().getContextClassLoader().getResourceAsStream(Constants.MessageInput)){
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readValue(inputStream ,
JsonNode.class);
json = mapper.writeValueAsString(jsonNode);
}
catch(Exception e){
throw new RuntimeException(e);
}
I have list of json files as below:
At the moment, T.json file is empty. All the other files already have some text. What I need is to create something like this:
1.At the beginning of the T.json file add sth like
{
"T": [
2.Copy text from e.g. T_Average.json and T_Easy.json to T.json file
3.At the end of T.json file add this:
]
}
So at the end of program execution I need to have in my T.json sth like:
{
"T": [
text from T_Average.json
text from T_Easy.json
]
}
So how can I add text from 1st and 3rd step to the file?
And how can I copy everything from other files to T.json file?
I have already tried some solutions like this:
try(FileWriter fw = new FileWriter("T.json", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw))
{
out.println("the text");
out.println("more text");
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
or like this one:
try {
String data = " This is new content";
File file = new File(FILENAME);
if (!file.exists()) {
file.createNewFile();
}
fw = new FileWriter(file.getAbsoluteFile(), true);
bw = new BufferedWriter(fw);
bw.write(data);
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
but all the time, after line with fw = new FileWriter() it was jumping right to the catch clause.
So one more time:
How can I add text from 1st and 3rd step to the file?
And how can I copy everything from other files to T.json file?
Thanks :)
Try
1. Add following methods getJsonFromAssetFile and writeFile to your code
2. Read json file
String content = getJsonFromAssetFile("T_Difficult.json");
3 Create final json (as mentioned)
JSONObject finalJson = new JSONObject();
try {
JSONObject jsonObject = new JSONObject(content);
JSONArray jsonArray = new JSONArray();
jsonArray.put(jsonObject);
finalJson.put("T", jsonArray);
} catch (JSONException e) {
e.printStackTrace();
}
4. Write final json to file
writeFile(finalJson.toString().getBytes());
writeFile
public static void writeFile(byte[] data, File file) throws IOException {
BufferedOutputStream bos = null;
try {
FileOutputStream fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(data);
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
getJsonFromAssetFile
public static String getJsonFromAssetFile(Context context, String jsonFileName) {
String json = null;
try {
InputStream is = context.getAssets().open(jsonFileName);
int size = is.available ();
byte[] buffer = new byte[size];
is.read (buffer);
is.close ();
json = new String(buffer, "UTF-8");
}
catch(IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
NOTE: Read json asset file using getJsonFromAssetFile method and Write file on internal/external storage and provide proper path to writeFile method
I'm trying to save user settings to a file, from where I can read the later. But I cant get it to work properly. I've tried reading up on this, but I'm still having problems.
Map<String, String> userSettings = new HashMap<>();
public void updateUserSettings(){
userSettings.clear();
userSettings.put("item0", item0);
userSettings.put("item1", item1);
userSettings.put("item2", item2);
userSettings.put("item3", item3);
userSettings.put("item4", item4);
userSettings.put("item5", item5);
userSettings.put("item6", item6);
userSettings.put("item7", item7);
userSettings.put("i0", Float.toString(i0));
userSettings.put("i1", Float.toString(i1));
userSettings.put("i2", Float.toString(i2));
userSettings.put("i3", Float.toString(i3));
userSettings.put("i4", Float.toString(i4));
userSettings.put("i5", Float.toString(i5));
userSettings.put("i6", Float.toString(i6));
userSettings.put("i7", Float.toString(i7));
userSettings.put("huvudMaskin", huvudMaskin);
userSettings.put("minorMaskin1", minorMaskin1);
userSettings.put("minorMaskin2", minorMaskin2);
userSettings.put("maskinTid", Float.toString(maskinTid));
writeSettings();
}
public void writeSettings() {
try
{
FileOutputStream fos = context.openFileOutput("test.ser", Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(userSettings);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void readSetttings() {
try
{
FileInputStream fileInputStream = new FileInputStream(context.getFilesDir()+"test.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myHashMap = (Map)objectInputStream.readObject();
userSettings = null;
userSettings = myHashMap;
}
catch(ClassNotFoundException | IOException | ClassCastException e) {
e.printStackTrace();
}
executeSettings();
}
I have both read and write rights to the app.
Im not getting anything out of this. I've checked the hashmap, and it works as intended. I have also tried a lot of different approaches, and the only thing I managed to get working was saving strings to a .txt file.
private String subFolder = "/userdata";
private String file = "test.ser";
public void writeSettings() {
File cacheDir = null;
File appDirectory = null;
if (android.os.Environment.getExternalStorageState().
equals(android.os.Environment.MEDIA_MOUNTED)) {
cacheDir = getApplicationContext().getExternalCacheDir();
appDirectory = new File(cacheDir + subFolder);
} else {
cacheDir = getApplicationContext().getCacheDir();
String BaseFolder = cacheDir.getAbsolutePath();
appDirectory = new File(BaseFolder + subFolder);
}
if (appDirectory != null && !appDirectory.exists()) {
appDirectory.mkdirs();
}
File fileName = new File(appDirectory, file);
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(fileName);
out = new ObjectOutputStream(fos);
out.writeObject(userSettings);
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null)
fos.flush();
fos.close();
if (out != null)
out.flush();
out.close();
} catch (Exception e) {
}
}
}
public void readSetttings() {
File cacheDir = null;
File appDirectory = null;
if (android.os.Environment.getExternalStorageState().
equals(android.os.Environment.MEDIA_MOUNTED)) {
cacheDir = getApplicationContext().getExternalCacheDir();
appDirectory = new File(cacheDir + subFolder);
} else {
cacheDir = getApplicationContext().getCacheDir();
String BaseFolder = cacheDir.getAbsolutePath();
appDirectory = new File(BaseFolder + subFolder);
}
if (appDirectory != null && !appDirectory.exists()) return; // File does not exist
File fileName = new File(appDirectory, file);
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(fileName);
in = new ObjectInputStream(fis);
Map<String, String> myHashMap = (Map<String, String> ) in.readObject();
userSettings = myHashMap;
System.out.println("count of hash map::"+userSettings.size() + " " + userSettings);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(fis != null) {
fis.close();
}
if(in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Your problem is very simple: you are using two different file names when writing the data resp. reading it.
FileOutputStream fos = context.openFileOutput("test.ser", Context.MODE_PRIVATE);
vs.
FileInputStream fileInputStream = new FileInputStream(context.getFilesDir()+"test.ser");
And, most likely, your reading code did throw an IOException at you, telling you something about trying to open a file that doesn't exist.
Thus, the real take-away/answer here: read those exception messages very carefully. Typically, they tell you exactly what the problem is!
Change these lines :
public void readSetttings(){
String path=context.getFilesDir() + File.seprator + "test.ser";
if(! new File(path).exists() ){
//throw NullPointerException ;
//return;
/*
*you can choose one of these
*pay attention : when choose NullPointerException you shold add throws Exceptions on your method
*/
}
try{
FileInputStream fileInputStream =context.openFileInput("test.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myHashMap = (Map)objectInputStream.readObject();
userSettings = myHashMap;
}catch(ClassNotFoundException | IOException | ClassCastException e) {
e.printStackTrace();
}
executeSettings();
}
If it is only primitives that you want to store then you should be using SharedPreferences which Android provides out of the box.
public static final String PREFS = "usersettings";
#Override
protected void onCreate(Bundle b){
.....
// read user settings on start
SharedPreferences settings = getSharedPreferences(PREFS, 0);
int someId = settings.getInteger("someId", 0);
setSomeId(id);
}
#Override
protected void onStop(){
.....
SharedPreferences settings = getSharedPreferences(PREFS, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInteger("someId", mSomeId);
// commit changes on exit
editor.commit();
}
I am trying to extract data from Json string which is obtained by a response using only Java code.
I am posting my Java code here.
OUTPUT:
Entering into while loop
[{"name":"Frank","food":"pizza","quantity":3}]
This is my Java code.
public void receive()
{
System.out.println("Entering into sendNote method");
try {
// make json string,
String json = "{\"name\":\"Frank\",\"food\":\"pizza\",\"quantity\":3}";
// send as http get request
URL url1 = new URL("http://myurl/file.php?usersJSON="+userList);
URLConnection conn1= url1.openConnection();
//I am receiving exactly what I have sent....
BufferedReader rd = new BufferedReader(new InputStreamReader(conn1.getInputStream()));
String line;
while ((line = rd.readLine()) != null)
{
System.out.println("Entering into while loop");
System.out.println(line);// line contains the received json parameters
//I want to enter the recieved parameters into my database
//
//
//
//I need the solution right here....
}
rd.close();
}
catch (Exception e)
{
System.out.println("Error Occured while receiving");
e.printStackTrace();
}
}
Thank you !!!!!
#Ankur:
This is how I tried,
# Lahiru Prasanna, #ankur-singhal
Thanks a lot.!!
I think that you successfully got HttpResponse.here variable called response is HttpResponse.
// Could do something better with response.
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(content));
String line;
try {
while ((line = reader.readLine()) != null) {
builder.append(line);
}
content.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
JSONObject jsonObject = new JSONObject(builder.toString());
} catch (JSONException e) {
System.out.println("Error parsing data " + e.toString());
}
}
} catch (Exception e) {
System.out.println("Error: " + e.toString());
System.out.println( "" + e.toString());
System.out.println("" + e.toString());
}
And important thing is never use Strings for json operations.
you can retrieve your data from jsonObject like this
String name = jsonObject.getString("name");
There are few ways to achive the same.
1.) Create a response pojo
MyResponse ob = new ObjectMapper().readValue(jsonString, MyResponse.class);
// then call getters on above.
2.) Get key/values
JSONObject json = (JSONObject)new JSONParser().parse(""name":"Frank","food":"pizza","quantity":3}");
System.out.println("name=" + json.get("name"));
System.out.println("width=" + json.get("food"));
3.) Converting Json to HashMap
public static void main(String[] args) {
try {
jsonToMap("{\"name\":\"Frank\",\"food\":\"pizza\",\"quantity\":3}");
} catch (JSONException e) {
e.printStackTrace();
}
}
public static void jsonToMap(String t) throws JSONException {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject jObject = new JSONObject(t);
Iterator<?> keys = jObject.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
String value = jObject.getString(key);
map.put(key, value);
}
System.out.println("json : " + jObject);
System.out.println("map : " + map);
}
output
json : {"name":"Frank","food":"pizza","quantity":3}
map : {food=pizza, name=Frank, quantity=3}
Here is the code:
Thread clientThread = new Thread() {
#Override
public void run() {
try {
client = new Client();
quest = client.readFile();
Log.v("Client string", quest);
//File file = new File(myContext.getFilesDir(), "questionnaire.xml");
//BufferedWriter bw = new BufferedWriter(new FileWriter(file));
//bw.write(quest);
File tempFile = File.createTempFile("questionnaire", ".xml");
FileOutputStream fout = new FileOutputStream(tempFile);
PrintStream out = new PrintStream(fout);
out.println(quest);//InputStream stream = new ByteArrayInputStream(quest.getBytes("UTF-8"));
//getResources().op
try {
Serializer serializer = new Persister();
responseToQuestionnaire = serializer.read(ResponseToQuestionnaire.class, tempFile);
}
catch(Exception e) {}
Log.v("Let's seeeeee",responseToQuestionnaire.getQuestionnaireTemplate().toString());
} catch (Exception e1) {
e1.printStackTrace();
}
// try {
// OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
// openFileOutput(currentQuestionnaire.getName(),
// Context.MODE_PRIVATE));
// outputStreamWriter.write(client.readFile());
// outputStreamWriter.close();
// } catch (IOException e) {
// Log.e("Exception", "File write failed: " + e.toString());
// }
}
};
clientThread.start();
The code throws a Null Pointer exception even when quest is a full length string that prints in log perfectly fine. I tried multiple ways of saving the file but SimpleXML doesn't serialize string... only XML files.
Buffered streams don't necessarily write the data until they have to. Try closing the output stream before you call the read() method.