ArrayList to Byte and vice versa - java

Hi I need to store ArrayList in database of my project, for that I need some suggestion to store ArrayList into DB by means of some techniques like ArrayList to Byte[] and store byte[] in DB and retreive my byte[] from DB and convert into my original ArrayList in Java

I assume you're talking about Java's ArrayList (you didn't mention the language you have in mind).
In fact, there was a vary similar question: Serializing Arraylists
Just serialize a list, and insert it to BLOB column. Then you can fetch it from DB and deserialize it.
Edit:
This is a piece of code you can use to serialize your ArrayList:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream ooStream = new ObjectOutputStream(baos);
ooStream.writeObject(myList);
ooStream.close();
} catch(IOException e) {
throw new RuntimeException(e);
} finally {
try {
baos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
byte[] serializedData = baos.toByteArray();
Having the data as byte[] you can now store it in bytea / BLOB column.
I hope this helps.

Related

How can I create a truststore from a base64 encoded String?

I have a String that is encoded in base64, I need to take this string, decode it and create a truststore file, but when I do that, the final file is not valid. Here is my code:
public static void buildFile() {
String exampleofencoded = "asdfasdfasdfadfa";
File file = new File("folder/file.jks");
try (FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos))
{
Base64.Decoder decoder = Base64.getDecoder();
String decodedString =new String(decoder.decode(exampleofencoded).getBytes());
dos.writeBytes(decodedString);
}
catch (IOException e) {
System.out.println("Error creating file");
}
catch(NullPointerException e) {
System.out.println(e.getMessage();
}
}
The problem is two-fold.
You're converting a byte[] array to String, which is a lossy operation for actual binary data for most character sets (except maybe iso-8859-1).
You're using DataOutputStream, which is not a generic output stream, but intended for a specific serialization format of primitive types. And specifically its writeBytes method comes with an important caveat ("Each character in the string is written out, in sequence, by discarding its high eight bits."), which is one more reason why only using iso-8859-1 will likely work.
Instead, write the byte array directly to the file
public static void buildFile() {
String exampleofencoded = "asdfasdfasdfadfa";
File file = new File("folder/file.jks");
try (FileOutputStream fos = Files.newOutputStream(file.toPath()) {
Base64.Decoder decoder = Base64.getDecoder();
byte[] decodedbytes = decoder.decode(exampleofencoded);
fos.write(decodedbytes);
} catch (IOException e) {
System.out.println("Error creating file");
}
}
As an aside, you shouldn't catch NullPointerException in your code, it is almost always a problem that can be prevented by careful programming and/or validation of inputs. I would usually also advise against catch the IOException here and only printing it. It is probably better to propagate that exception as well, and let the caller handle it.

Spring data jpa persisting large List<String> property

What is the right way to persist a huge List<String> entity property with Spring jpa (postgresql db)? I've been converting it to byte[] which was stored as bytea in db , however it causes different formatting troubles (even simply rewriting the list).
List<String> can be as big as 10.000.000 entities. sometimes i just need to take the list, change a few elements and write it back.
As i understand, other options are:
use ElementCollection - which i think isn't the solution for such large lists.
Store it as large string with split characters - guess that isn't very efficient option either.
currently i use these methods to transform the list to/from byte[]:
public static List<String> bytesToStringListByInputStream(byte[] bytes) {
List<String> lines;
if (bytes == null) {
return lines;
}
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
DataInputStream in = new DataInputStream(bais);
try {
while (in.available() > 0) {
lines.add(in.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
}
return lines;
}
public static byte[] arrayListToByteArray(List<String> list){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
for (String element : list) {
try {
out.writeUTF(element + System.lineSeparator());
} catch (IOException e) {
e.printStackTrace();
}
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
return baos.toByteArray();
}
entity:
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class UserFile implements Serializable {
...some fields...
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private byte[] fileData;
however in different cases after changing the list and persisting it, random characters appear in ouput lines - sometimes numbers or special symbols.
I guess i can find find a reason why it happenning, but in any case - is this a right way to persist a large lists (through byte[] jpa entity field and bytea postgresql field)?

Reliably convert any object to String and then back again

Is there a reliable way to convert any object to a String and then back again to the same Object? I've seen some examples of people converting them using toString() and then passing that value into a constructor to reconstruct the object again but not all objects have a constructor like this so that method wont work for all cases. What way will?
Yes, it is called serialization!
String serializedObject = "";
// serialize the object
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(myObject);
so.flush();
serializedObject = bo.toString();
} catch (Exception e) {
System.out.println(e);
}
// deserialize the object
try {
byte b[] = serializedObject.getBytes();
ByteArrayInputStream bi = new ByteArrayInputStream(b);
ObjectInputStream si = new ObjectInputStream(bi);
MyObject obj = (MyObject) si.readObject();
} catch (Exception e) {
System.out.println(e);
}
This is the code:
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(stringList);
so.flush();
redisString = new String(Base64.encode(bo.toByteArray()));
}
catch (Exception e) {
e.printStackTrace();
}
try {
byte b[] = Base64.decode(redisString.getBytes());
ByteArrayInputStream bi = new ByteArrayInputStream(b);
ObjectInputStream si = new ObjectInputStream(bi);
List<String> stringList2 = (List<String>)si.readObject();
System.out.println(stringList2.get(1));
}
catch (Exception e) {
e.printStackTrace();
}
Serialize to byte array, convert to Base64. Then decode Base64 back to byte array and deserialize.
None will work in all cases. An object may, e.g., contain references to other JVMs handling their state, and this state may be not available for you to restore.
Additional problems you're going to meet will include open streams, listening sockets, and almost anything else from the outer world.
There's no need to repeat that most at least two of Java core engineers say that serialization was one of the greatest mistakes a single worst feature in Java, that is, after finalization. (I do love serialization nevertheless, it's handy. But it won't always work.)
One way is to use JSON. For implementation specific in Java, the answer might be given in this post:
java code corresponding to Newtonsoft.Json.JsonConvert.SerializeObject(Object source,Newtonsoft.Json.JsonSerializerSettings()) in .net?
Using JSON is reliable enough that it's used for web application development (Ajax).
Yes, it is Serialization You can use, ObjectInputStream.readObject and ObjectOutputStream.writeObject. Please see below example:
MyClass myClass = new MyClass();
FileOutputStream fileStream = new FileOutputStream("myObjectFile.txt");
ObjectOutputStream os = new ObjectOutputStream(fileStream);
os.writeObject(os);
os.close();
FileInputStream fileInStream = new FileInputStream("myObjectFile.txt");
ObjectInputStream ois = new ObjectInputStream(fileInStream);
MyClass myClass2 = ois.readObject();
ois.close();
You can use SerializationUtils from org.apache.commons.
It provides the methods serialize and deserialize

Java: how to serialize a 3rd party library produced Java Object?

So I am using a proprietary java library in a project which I don't have access to source code.
It throws a Message object, and obviously I can't implement Serializable. It's generated throughout runtime.
what are my options? Is there a way to serialize the Message object into a byte array and back into the object?
UPDATE: I was able to serialize the object to JSON (http://code.google.com/p/json-io/) but couldn't convert it back to an object as it returns null. So I am trying to convert it to byte array using the code below. Still not working.
public byte[] toByteArray (Object obj)
{
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
oos.close();
bos.close();
bytes = bos.toByteArray ();
}
catch (IOException ex) {
//TODO: Handle the exception
}
return bytes;
}
public Object toObject (byte[] bytes)
{
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
ObjectInputStream ois = new ObjectInputStream (bis);
obj = ois.readObject();
}
catch (IOException ex) {
//TODO: Handle the exception
}
catch (ClassNotFoundException ex) {
//TODO: Handle the exception
}
return obj;
}
You could write a wrapper that is serializable and stores everything you need to recreate the Message object.
XStream is one way to go.
Sure, you just can't use the java.lang.Serializable mechanism.
Choose any format: XML, JSON, protocol buffer, or something else that might work for you.
Now you're responsible for both ends of the conversation: serialization and deserialization.
If the object is a Java bean, you can use java.beans.XMLEncoder and java.beans.XMLDecoder for serialization.

Blob object not working properly even though the class is seralized

I have class which is seralized and does convert a very large amount of data object to blob to save it to database.In the same class there is decode method to convert blob to the actual object.Following is the code for encode and decode of the object.
private byte[] encode(ScheduledReport schedSTDReport)
{
byte[] bytes = null;
try
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(schedSTDReport);
oos.flush();
oos.close();
bos.close();
//byte [] data = bos.toByteArray();
//ByteArrayOutputStream baos = new ByteArrayOutputStream();
//GZIPOutputStream out = new GZIPOutputStream(baos);
//XMLEncoder encoder = new XMLEncoder(out);
//encoder.writeObject(schedSTDReport);
//encoder.close();
bytes = bos.toByteArray();
//GZIPOutputStream out = new GZIPOutputStream(bos);
//out.write(bytes);
//bytes = bos.toByteArray();
}
catch (Exception e)
{
_log.error("Exception caught while encoding/zipping Scheduled STDReport", e);
}
decode(bytes);
return bytes;
}
/*
* Decode the report definition blob back to the
* ScheduledReport object.
*/
private ScheduledReport decode(byte[] bytes)
{
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ScheduledReport sSTDR = null;
try
{
ObjectInputStream ois = new ObjectInputStream(bais);
//GZIPInputStream in = new GZIPInputStream(bais);
//XMLDecoder decoder = new XMLDecoder(in);
sSTDR = (ScheduledReport)ois.readObject();//decoder.readObject();
//decoder.close();
}
catch (Exception e)
{
_log.error("IOException caught while decoding/unzipping Scheduled STDReport", e);
}
return sSTDR;
}
The problem here is whenver I change something else in this class
means any other method,a new class version is created and so the new version the class is unable to decode the originally encoded blob object. The object which I am passing for encode is also seralized object but this problem exists. Any ideas thanks
Yup, Java binary serialization is pretty brittle :(
You can add a static serialVersionUID field to the class so that you can control the version numbers... this should prevent problems due to adding methods. You'll still run into potential issues when fields are added though. See the JavaDocs for Serializable for some more details.
You might want to consider using another serialization format such as Protocol Buffers to give you more control though.
You can implement java.io.Externalizable so that you are able to control what is serialized and expected in deserialization.

Categories