Make JsonNode Serializable - java

This seems to be simple but I failed to get a serialized JsonNode deserialized. Here is my test class
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Foo implements Serializable {
private String string;
private transient JsonNode jsonNode;
public Foo(String string, JsonNode jsonNode) {
this.string = string;
this.jsonNode = jsonNode;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
if (this.jsonNode != null) out.writeObject((new ObjectMapper()).writeValueAsBytes(this.jsonNode));
// out.writeObject(this.jsonNode.textValue());
}
private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {
in.defaultReadObject();
this.jsonNode = (new ObjectMapper()).readValue(in, JsonNode.class);
}
}
When I tried to deserialize I got this error
com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
Here is the unit test
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.testng.annotations.Test;
import java.io.*;
import static org.testng.Assert.assertEquals;
public class FooTest {
#Test
public void testSerialization() {
JsonNodeFactory nodeFactory = new JsonNodeFactory(false);
ObjectNode node = nodeFactory.objectNode();
ObjectNode child = nodeFactory.objectNode(); // the child
child.put("message", "test");
node.put("notification", child);
Foo foo = new Foo("Bar", node);
String fileName = "foo.ser";
try (
OutputStream file = new FileOutputStream(fileName);
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
){
output.writeObject(foo);
}
catch(IOException ex){
ex.getStackTrace();
}
Foo fooNew = null;
//deserialize the ser file
try(
InputStream file = new FileInputStream(fileName);
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
){
//deserialize the Object
fooNew = (Foo) input.readObject();
}
catch(ClassNotFoundException ex){
ex.printStackTrace();
}
catch(IOException ex){
ex.printStackTrace();
}
assertEquals(foo, fooNew);
}
}

Your read and write operations are not matched.
On the write side you use ObjectOutputStream.writeObject(Object) to write a byte[] containing the serialized JSON content. On the read side you try to read raw bytes off the stream with ObjectMapper.readValue(InputStream, Class) when you actually need to read a byte[] object first as that is what you wrote and then use ObjectMapper.readValue(byte[], Class).
Alternatively and probably a better solution is you could use ObjectMapper.writeValue(OutputStream, Object) instead on the write side.
Try this:
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
if(jsonNode == null){
out.writeBoolean(false);
} else {
out.writeBoolean(true);
new ObjectMapper().configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false).writeValue(out, jsonNode);
}
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
if(in.readBoolean()){
this.jsonNode = new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false).readValue(in, JsonNode.class);
}
}

Related

How can I use gson to create a set of key value pairs?

I currently have this code, how can I add to it so I can get a JsonObject from Gson to append it to an existing Json file?
private static void writeFile(File f, String w_username, String w_password) throws IOException{
Gson gson = new Gson();
JsonWriter writer = new JsonWriter(new FileWriter(f));
}
JSON structure does not allow just to append more data at the end of the file. In this case more suitable could be CSV format.
To solve your problem you need to read the whole file as JsonObject, add new "key-value" pair and save it back.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Objects;
public class GsonApp {
public static void main(String[] args) throws IOException {
File store = Files.createTempFile("store", "json").toFile();
// Add two users
JsonFileAppender jsonFileAppender = new JsonFileAppender();
jsonFileAppender.appendToObject(store, "jon", "ewemn!32");
jsonFileAppender.appendToObject(store, "rick", "923djks");
// Print whole file
System.out.println(String.join("", Files.readAllLines(store.toPath())));
}
}
class JsonFileAppender {
private final Gson gson;
public JsonFileAppender() {
this.gson = new GsonBuilder().create();
}
public void appendToObject(File jsonFile, String username, String password) throws IOException {
Objects.requireNonNull(jsonFile);
Objects.requireNonNull(username);
Objects.requireNonNull(password);
if (jsonFile.isDirectory()) {
throw new IllegalArgumentException("File can not be a directory!");
}
JsonObject node = readOrCreateNew(jsonFile);
node.addProperty(username, password);
writeToFile(jsonFile, node);
}
private JsonObject readOrCreateNew(File jsonFile) throws IOException {
if (jsonFile.exists() && jsonFile.length() > 0) {
try (BufferedReader reader = new BufferedReader(new FileReader(jsonFile))) {
return gson.fromJson(reader, JsonObject.class);
}
}
return new JsonObject();
}
private void writeToFile(File jsonFile, JsonObject node) throws IOException {
try (FileWriter writer = new FileWriter(jsonFile)) {
gson.toJson(node, writer);
}
}
}
Above code prints:
{"jon":"ewemn!32","rick":"923djks"}

How can I save an arraylist in a txt and load what is stored there?

I need to save an arraylist in a txt when I close a window and load it when I return to open the program so that it shows what is saved in a JTable.
This is my arraylist
ArrayList<Usuarios> Encuestados = new ArrayList<>();
And I'm saving in this way but I would not know how to load the saved txt to the arraylist
public void guardarTxt() throws FileNotFoundException, IOException, ClassNotFoundException{
FileOutputStream fout=new FileOutputStream("Datos/Encuestados.txt");
try (ObjectOutputStream out = new ObjectOutputStream(fout)) {
out.writeObject(Encuestados);
}
}
You just need to serialize and deserialize the objects in the array. You can search for serialize and deserialize objects in java. I have implemented a code below.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
class Usuarios implements Serializable { // will need to implement Serializable class
private static final long serialversionUID = 129348938L; // this is needed
String name;
int age;
// Default constructor
public Usuarios(String name, int age) {
this.name = name;
}
}
public class Main { // Example class for Serialization and deserialization
// method for printing the object
public static void printdata(Usuarios object1) {
System.out.println("name = " + object1.name);
System.out.println("age = " + object1.age);
}
public static void serialize(ArrayList<Usuarios> list, String filename){
// Serialization
try {
// Saving of object in a file
FileOutputStream file = new FileOutputStream
(filename);
ObjectOutputStream out = new ObjectOutputStream
(file);
// Method for serialization of object
out.writeObject(list);
out.close();
file.close();
System.out.println("Object has been serialized");
}
catch (IOException ex) {
System.out.println("IOException is caught");
}
}
public static ArrayList<Usuarios> deserialize(String filename){
// Deserialization
try {
// Reading the object from a file
FileInputStream file = new FileInputStream
(filename);
ObjectInputStream in = new ObjectInputStream
(file);
// Method for deserialization of object
ArrayList<Usuarios> list = (ArrayList<Usuarios>)in.readObject();
System.out.println("Object has been deserialized");
in.close();
file.close();
return list;
}
catch (IOException ex) {
System.out.println("IOException is caught");
}
catch (ClassNotFoundException ex) {
System.out.println("ClassNotFoundException" +
" is caught");
}
return null;
}
public static void main(String[] args) {
Usuarios object1 = new Usuarios ("ab", 20);
Usuarios object2 = new Usuarios ("cd", 21);
String filename = "s.txt";
ArrayList<Usuarios> EncuestadosBeforeSerialization = new ArrayList<>();
EncuestadosBeforeSerialization.add(object1);
EncuestadosBeforeSerialization.add(object2);
System.out.println("Data before Deserialization.");
for (Usuarios object: EncuestadosBeforeSerialization) {
printdata(object);
};
serialize(EncuestadosBeforeSerialization, filename);
System.out.println("\n\nData will be Deserialize.");
ArrayList<Usuarios> EncuestadosAfterSerialization = deserialize(filename);
System.out.println("Data after Deserialization.");
for (Usuarios object: EncuestadosAfterSerialization) {
printdata(object);
};
}
}
Result:
Data before Deserialization.
name = ab
age = 0
name = cd
age = 0
Object has been serialized
Data will be Deserialize.
Object has been deserialized
Data after Deserialization.
name = ab
age = 0
name = cd
age = 0

How to make BufferedInputStream Serializable?

I need to make java BufferedInputStream Serializable. Are there any alternatives or any other way to implement it?
Do yo see any issue in this implementation
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.Serializable;
public class SerializableBufferedInputStream extends BufferedInputStream implements Serializable
{
public SerializableBufferedInputStream(InputStream in)
{
super(in);
}
public SerializableBufferedInputStream(InputStream in, int size)
{
super(in, size);
}
}
First of all, BufferedInputStream Creates a BufferedInputStream and saves its argument, the input stream in, for later use.
but you are saying Serializable which means converting the state of an object into a byte stream
so why do you need to convert it ??
This thing may help you check (Provide your Code in case you want other than this)
public class MainClass {
public static void main(String[] args) throws Exception {
Punk obj1 = new Punk("A");
Punk obj2 = new Punk("B");
Punk obj3 = new Punk("V");
ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(
new FileOutputStream("C:/punkObjects.bin")));
objectOut.writeObject(obj1); // Write object
objectOut.writeObject(obj2); // Write object
objectOut.writeObject(obj3); // Write object
objectOut.close(); // Close the output stream
ObjectInputStream objectIn = null;
int objectCount = 0;
punk object = null;
objectIn = new ObjectInputStream(new BufferedInputStream(new FileInputStream(
"C:/punkObjects.bin")));
// Read from the stream until we hit the end
while (objectCount < 3) {
object = (punk) objectIn.readObject();
objectCount++;
System.out.println(object);
}
objectIn.close();
}
}
class Punk implements Serializable {
String str;
public Punk(String s) {
str = s;
}
}

Write and read object to and from file

I want to read and write an object to a file. This is my attempt:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
public class SaveOpen implements Serializable
{
private static String fileName;
private ArrayList<Person> list = new ArrayList<Person>();
public SaveOpen() {
fileName = "file.txt";
}
//Reader
public static Object deserialize() throws IOException,
ClassNotFoundException {
FileInputStream fis = new FileInputStream(fileName);
BufferedInputStream bis = new BufferedInputStream(fis);
ObjectInputStream ois = new ObjectInputStream(bis);
Object obj = ois.readObject();
ois.close();
return obj;
}
//Writer
public static void serialize(Object obj)
throws IOException {
FileOutputStream fos = new FileOutputStream(fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.close();
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public ArrayList<Person> getListPersons() {
return list;
}
}
However, I do not know if this is the correct way nor how to implement this in a class. The object is Person and I want to save and read that object from a file. Is it supposed to be done to a .txt file? Anyone who can clearify things? Thanks!
if you want the file to be human readable i would suggest to save it as xml.
Example :
Object Class
import java.io.Serializable;
public class Person implements Serializable
{
private String username;
private int id;
public String UserName() { return username; }
public void setUserName(String str) { username = str;}
public int ID() { return id; }
public void setID(int ID) { id = ID; }
}
-Serializer/Deserializer
import Settings.Person;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class XmlSerializer
{
//File path to serialize to and deserialize from
private static final String SERIALIZED_FILE_NAME = "yourSavePath.xml";
//Insert person object and save as xml file to chosen filepath
public static void Serialize(Person person)
{
try
{
FileOutputStream os = new FileOutputStream(SERIALIZED_FILE_NAME);
XMLEncoder encoder = new XMLEncoder(os);
encoder.writeObject(person);
encoder.close();
}
catch(FileNotFoundException ex)
{
System.out.println(ex.getMessage());
}
}
//Deserialize xml file into person object
public static Person Deserialize()
{
try
{
FileInputStream os = new FileInputStream(SERIALIZED_FILE_NAME);
XMLDecoder decoder = new XMLDecoder(os);
Person p = (Person)decoder.readObject();
decoder.close();
return p;
}
catch(FileNotFoundException ex)
{
System.out.println(ex.getMessage());
}
return null;
}
}
You're doing it right already. You can safe Objects in a txt file altough it makes not much sense, I'd rather go with a binary file.
To store multiple Objects in a single File, simply pack them in a Collection and then serialize the Collection object.
When reading an Object from a File, check its Class via instanceof and cast it to whatever it is.

How to remove a single objects stored on Java FileOutputStream

I have used this code to store Object to a file:
try{
FileOutputStream saveFile=new FileOutputStream("SaveObj.sav");
ObjectOutputStream save = new ObjectOutputStream(saveFile);
save.writeObject(x);
save.close();
}
catch(Exception exc){
exc.printStackTrace();
}
}
}
How remove the single Object??
How clear the file??
Well, emptying out a file is very easy -- just open it for writing, and close it again:
new FileOutputStream("SaveObj.sav").close();
That will empty it out. If you were trying to erase one object out of many, though, that's a lot more complicated. You'd either have to read in all the objects and write out only the ones you want to keep, or you'd have to keep an index of the file offsets at which each object starts (probably in a separate file.) At that point you'd want to consider using an object database instead.
Ernest is right in that a removal of a particular object from the object-stream is slightly more complicated. He is also right that when you want to empty a file, you can simply open it for writing and close it. But if you want to remove it from the file-system, it is fine to do it using the File object (do not forget to handle the exceptions and return values correctly). The following example may not be perfect, but it should give you a hint on how to achieve your goals with pure Java. Hope this helps...
package test;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
String filename = "object.serialized";
{
List objects = new ArrayList();
objects.add("String1");
objects.add("String2");
objects.add("String3");
writeObjectsToFile(filename, objects);
}
{
List objects = readObjectsFromFile(filename);
objects.remove(1);
writeObjectsToFile(filename, objects);
}
{
List objects = readObjectsFromFile(filename);
for (Object object : objects) {
System.out.println(object);
}
}
emptyFile(filename);
deleteFile(filename);
}
private static void emptyFile(String filename) throws IOException {
OutputStream os = null;
try {
os = new FileOutputStream(filename);
} finally {
if (os != null) {
os.close();
}
}
}
private static void deleteFile(String filename) {
File f = new File(filename);
if (f.delete()) {
System.out.println(filename + " deleted sucessfully...");
} else {
System.out.println(filename + " deletion failed!");
}
}
private static void writeObjectsToFile(String filename, List objects) throws IOException {
OutputStream os = null;
try {
os = new FileOutputStream(filename);
ObjectOutputStream oos = new ObjectOutputStream(os);
for (Object object : objects) {
oos.writeObject(object);
}
oos.flush();
} finally {
if (os != null) {
os.close();
}
}
}
private static List readObjectsFromFile(String filename) throws IOException, ClassNotFoundException {
List objects = new ArrayList();
InputStream is = null;
try {
is = new FileInputStream(filename);
ObjectInputStream ois = new ObjectInputStream(is);
while (true) {
try {
Object object = ois.readObject();
objects.add(object);
} catch (EOFException ex) {
break;
}
}
} finally {
if (is != null) {
is.close();
}
}
return objects;
}
}
Outputs:
String1
String3
object.serialized deleted sucessfully...
I know there was a long time from this subject, but just to help future coming people, what works for me was to write the object again as a null value:
public static void writeIncidentsObjectsInCache(Object object) throws IOException {
writeObject(INCIDENTS_CACHE, object); }
public static Object readIncidentsObjectFromCache() throws IOException,
ClassNotFoundException {
return readObject(INCIDENTS_CACHE); }
public static void clearIncidents() throws IOException, ClassNotFoundException {
writeIncidentsObjectsInCache(null); }
public static void writeObject(String key, Object object) throws IOException {
FileOutputStream fos = TheAAApp.getApp().openFileOutput(key, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.close();
fos.close();
}
public static Object readObject(String key) throws IOException,
ClassNotFoundException {
FileInputStream fis = TheAAApp.getApp().openFileInput(key);
ObjectInputStream ois = new ObjectInputStream(fis);
Object object = ois.readObject();
return object;
}

Categories