Unable to serialize convert java POJO class into a byte array - java

How to convert java POJO class into a byte array as I wanted to save the object into a gz file in S3
I get this exception Caused by: java.io.NotSerializableException
public byte[] compressData(User user) throws IOException {
byte[] data;
try(ByteArrayOutputStream byteStream = new ByteArrayOutputStream();) {
try (GZIPOutputStream objectOutputStream = new GZIPOutputStream(byteStream);) {
try (ObjectOutputStream zipStream = new ObjectOutputStream(objectOutputStream);) {
zipStream.writeObject(user);
}
data = byteStream.toByteArray();
} catch (Exception e) {
throw new IOException(e);
}
}
return data;
}

you can use SerializationUtils.java from ApacheCommonslang dependency.
For serialization
byte[] data = SerializationUtils.serialize(**POJO_Object_Name**);
for deserialize:
POJO_Class_Name **POJO_Object_Name** = SerializationUtils.deserialize(data)

private final Type userType = new TypeToken<User>() {}.getType();
private final Gson = new Gson();
compressData(gson.toJson(user,userType));
public static byte[] compressData(String user) throws IOException {
byte[] data;
try(ByteArrayOutputStream byteStream = new ByteArrayOutputStream();){
try(GZIPOutputStream zipStream = new GZIPOutputStream(byteStream);){
zipStream.write(data.getBytes(StandardCharsets.UTF_8));
}
data = byteStream.toByteArray();
} catch(Exception e) {
throw new IOException("Error while compressing the User record ", e);
}
return data;
}

Related

ObjectInputStream header problems [duplicate]

I am trying to convert a ArrayList object to a byte string so it can be sent via sockets. When I run this code it converts to a string properly but when I try to convert it back I get the exception "java.io.StreamCorruptedException: invalid stream header: EFBFBDEF". Other answers I looked at on here didn't really help as I am using the matching ObjectOutputStream and ObjectInputStream. Sorry if there is a simple fix as I am new to working with stream objects.
try {
ArrayList<String> text = new ArrayList<>();
text.add("Hello World!");
String byteString = Utils.StringUtils.convertToByteString(text);
ArrayList<String> convertedSet = (ArrayList<String>) Utils.StringUtils.convertFromByteString(byteString);
VCS.getServiceManager().addConsoleLog(convertedSet.get(0));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
public static String convertToByteString(Object object) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos)) {
out.writeObject(object);
final byte[] byteArray = bos.toByteArray();
return new String(byteArray);
}
}
public static Object convertFromByteString(String byteString) throws IOException, ClassNotFoundException {
final byte[] bytes = byteString.getBytes();
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInput in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
I figured it out. I had to use Base64 encoding. The conversion methods have to be changed to the following:
public static String convertToByteString(Object object) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos)) {
out.writeObject(object);
final byte[] byteArray = bos.toByteArray();
return Base64.getEncoder().encodeToString(byteArray);
}
}
public static Object convertFromByteString(String byteString) throws IOException, ClassNotFoundException {
final byte[] bytes = Base64.getDecoder().decode(byteString);
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInput in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
String is not a container for binary data. You need to pass around the original byte array, or hex- or base64-encode it.
Better still, serialize directly to the socket and get rid of this altogether.

Is it possible to convert a custom ArrayList to an to byte array? [duplicate]

Let's say I have a serializable class AppMessage.
I would like to transmit it as byte[] over sockets to another machine where it is rebuilt from the bytes received.
How could I achieve this?
Prepare the byte array to send:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(yourObject);
out.flush();
byte[] yourBytes = bos.toByteArray();
...
} finally {
try {
bos.close();
} catch (IOException ex) {
// ignore close exception
}
}
Create an object from a byte array:
ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
ObjectInput in = null;
try {
in = new ObjectInputStream(bis);
Object o = in.readObject();
...
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
// ignore close exception
}
}
The best way to do it is to use SerializationUtils from Apache Commons Lang.
To serialize:
byte[] data = SerializationUtils.serialize(yourObject);
To deserialize:
YourObject yourObject = SerializationUtils.deserialize(data)
As mentioned, this requires Commons Lang library. It can be imported using Gradle:
compile 'org.apache.commons:commons-lang3:3.5'
Maven:
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
Jar file
And more ways mentioned here
Alternatively, the whole collection can be imported. Refer this link
If you use Java >= 7, you could improve the accepted solution using try with resources:
private byte[] convertToBytes(Object object) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos)) {
out.writeObject(object);
return bos.toByteArray();
}
}
And the other way around:
private Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
Can be done by SerializationUtils, by serialize & deserialize method by ApacheUtils to convert object to byte[] and vice-versa , as stated in #uris answer.
To convert an object to byte[] by serializing:
byte[] data = SerializationUtils.serialize(object);
To convert byte[] to object by deserializing::
Object object = (Object) SerializationUtils.deserialize(byte[] data)
Click on the link to Download org-apache-commons-lang.jar
Integrate .jar file by clicking:
FileName -> Open Medule Settings -> Select your module -> Dependencies -> Add Jar file and you are done.
Hope this helps.
I also recommend to use SerializationUtils tool. I want to make a ajust on a wrong comment by #Abilash. The SerializationUtils.serialize() method is not restricted to 1024 bytes, contrary to another answer here.
public static byte[] serialize(Object object) {
if (object == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
}
catch (IOException ex) {
throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
}
return baos.toByteArray();
}
At first sight, you may think that new ByteArrayOutputStream(1024) will only allow a fixed size. But if you take a close look at the ByteArrayOutputStream, you will figure out the the stream will grow if necessary:
This class implements an output stream in which the data is
written into a byte array. The buffer automatically grows as data
is written to it.
The data can be retrieved using toByteArray() and
toString().
Another interesting method is from com.fasterxml.jackson.databind.ObjectMapper
byte[] data = new ObjectMapper().writeValueAsBytes(JAVA_OBJECT_HERE)
Maven Dependency
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
If you are using spring, there's a util class available in spring-core. You can simply do
import org.springframework.util.SerializationUtils;
byte[] bytes = SerializationUtils.serialize(anyObject);
Object object = SerializationUtils.deserialize(bytes);
I would like to transmit it as byte[] over sockets to another machine
// When you connect
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
// When you want to send it
oos.writeObject(appMessage);
where it is rebuilt from the bytes received.
// When you connect
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
// When you want to receive it
AppMessage appMessage = (AppMessage)ois.readObject();
Spring Framework org.springframework.util.SerializationUtils
byte[] data = SerializationUtils.serialize(obj);
In case you want a nice no dependencies copy-paste solution. Grab the code below.
Example
MyObject myObject = ...
byte[] bytes = SerializeUtils.serialize(myObject);
myObject = SerializeUtils.deserialize(bytes);
Source
import java.io.*;
public class SerializeUtils {
public static byte[] serialize(Serializable value) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try(ObjectOutputStream outputStream = new ObjectOutputStream(out)) {
outputStream.writeObject(value);
}
return out.toByteArray();
}
public static <T extends Serializable> T deserialize(byte[] data) throws IOException, ClassNotFoundException {
try(ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
//noinspection unchecked
return (T) new ObjectInputStream(bis).readObject();
}
}
}
This is just an optimized code form of the accepted answer in case anyone wants to use this in production :
public static void byteArrayOps() throws IOException, ClassNotFoundException{
String str="123";
byte[] yourBytes = null;
// Convert to byte[]
try(ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);) {
out.writeObject(str);
out.flush();
yourBytes = bos.toByteArray();
} finally {
}
// convert back to Object
try(ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
ObjectInput in = new ObjectInputStream(bis);) {
Object o = in.readObject();
} finally {
}
}
code example with java 8+:
public class Person implements Serializable {
private String lastName;
private String firstName;
public Person() {
}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Override
public String toString() {
return "firstName: " + firstName + ", lastName: " + lastName;
}
}
public interface PersonMarshaller {
default Person fromStream(InputStream inputStream) {
try (ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
Person person= (Person) objectInputStream.readObject();
return person;
} catch (IOException | ClassNotFoundException e) {
System.err.println(e.getMessage());
return null;
}
}
default OutputStream toStream(Person person) {
try (OutputStream outputStream = new ByteArrayOutputStream()) {
ObjectOutput objectOutput = new ObjectOutputStream(outputStream);
objectOutput.writeObject(person);
objectOutput.flush();
return outputStream;
} catch (IOException e) {
System.err.println(e.getMessage());
return null;
}
}
}

How to Convert a user defined object to byte array [duplicate]

Let's say I have a serializable class AppMessage.
I would like to transmit it as byte[] over sockets to another machine where it is rebuilt from the bytes received.
How could I achieve this?
Prepare the byte array to send:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(yourObject);
out.flush();
byte[] yourBytes = bos.toByteArray();
...
} finally {
try {
bos.close();
} catch (IOException ex) {
// ignore close exception
}
}
Create an object from a byte array:
ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
ObjectInput in = null;
try {
in = new ObjectInputStream(bis);
Object o = in.readObject();
...
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
// ignore close exception
}
}
The best way to do it is to use SerializationUtils from Apache Commons Lang.
To serialize:
byte[] data = SerializationUtils.serialize(yourObject);
To deserialize:
YourObject yourObject = SerializationUtils.deserialize(data)
As mentioned, this requires Commons Lang library. It can be imported using Gradle:
compile 'org.apache.commons:commons-lang3:3.5'
Maven:
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
Jar file
And more ways mentioned here
Alternatively, the whole collection can be imported. Refer this link
If you use Java >= 7, you could improve the accepted solution using try with resources:
private byte[] convertToBytes(Object object) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos)) {
out.writeObject(object);
return bos.toByteArray();
}
}
And the other way around:
private Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
Can be done by SerializationUtils, by serialize & deserialize method by ApacheUtils to convert object to byte[] and vice-versa , as stated in #uris answer.
To convert an object to byte[] by serializing:
byte[] data = SerializationUtils.serialize(object);
To convert byte[] to object by deserializing::
Object object = (Object) SerializationUtils.deserialize(byte[] data)
Click on the link to Download org-apache-commons-lang.jar
Integrate .jar file by clicking:
FileName -> Open Medule Settings -> Select your module -> Dependencies -> Add Jar file and you are done.
Hope this helps.
I also recommend to use SerializationUtils tool. I want to make a ajust on a wrong comment by #Abilash. The SerializationUtils.serialize() method is not restricted to 1024 bytes, contrary to another answer here.
public static byte[] serialize(Object object) {
if (object == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
}
catch (IOException ex) {
throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
}
return baos.toByteArray();
}
At first sight, you may think that new ByteArrayOutputStream(1024) will only allow a fixed size. But if you take a close look at the ByteArrayOutputStream, you will figure out the the stream will grow if necessary:
This class implements an output stream in which the data is
written into a byte array. The buffer automatically grows as data
is written to it.
The data can be retrieved using toByteArray() and
toString().
Another interesting method is from com.fasterxml.jackson.databind.ObjectMapper
byte[] data = new ObjectMapper().writeValueAsBytes(JAVA_OBJECT_HERE)
Maven Dependency
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
If you are using spring, there's a util class available in spring-core. You can simply do
import org.springframework.util.SerializationUtils;
byte[] bytes = SerializationUtils.serialize(anyObject);
Object object = SerializationUtils.deserialize(bytes);
I would like to transmit it as byte[] over sockets to another machine
// When you connect
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
// When you want to send it
oos.writeObject(appMessage);
where it is rebuilt from the bytes received.
// When you connect
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
// When you want to receive it
AppMessage appMessage = (AppMessage)ois.readObject();
Spring Framework org.springframework.util.SerializationUtils
byte[] data = SerializationUtils.serialize(obj);
In case you want a nice no dependencies copy-paste solution. Grab the code below.
Example
MyObject myObject = ...
byte[] bytes = SerializeUtils.serialize(myObject);
myObject = SerializeUtils.deserialize(bytes);
Source
import java.io.*;
public class SerializeUtils {
public static byte[] serialize(Serializable value) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try(ObjectOutputStream outputStream = new ObjectOutputStream(out)) {
outputStream.writeObject(value);
}
return out.toByteArray();
}
public static <T extends Serializable> T deserialize(byte[] data) throws IOException, ClassNotFoundException {
try(ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
//noinspection unchecked
return (T) new ObjectInputStream(bis).readObject();
}
}
}
This is just an optimized code form of the accepted answer in case anyone wants to use this in production :
public static void byteArrayOps() throws IOException, ClassNotFoundException{
String str="123";
byte[] yourBytes = null;
// Convert to byte[]
try(ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);) {
out.writeObject(str);
out.flush();
yourBytes = bos.toByteArray();
} finally {
}
// convert back to Object
try(ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
ObjectInput in = new ObjectInputStream(bis);) {
Object o = in.readObject();
} finally {
}
}
code example with java 8+:
public class Person implements Serializable {
private String lastName;
private String firstName;
public Person() {
}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Override
public String toString() {
return "firstName: " + firstName + ", lastName: " + lastName;
}
}
public interface PersonMarshaller {
default Person fromStream(InputStream inputStream) {
try (ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
Person person= (Person) objectInputStream.readObject();
return person;
} catch (IOException | ClassNotFoundException e) {
System.err.println(e.getMessage());
return null;
}
}
default OutputStream toStream(Person person) {
try (OutputStream outputStream = new ByteArrayOutputStream()) {
ObjectOutput objectOutput = new ObjectOutputStream(outputStream);
objectOutput.writeObject(person);
objectOutput.flush();
return outputStream;
} catch (IOException e) {
System.err.println(e.getMessage());
return null;
}
}
}

How to read binary data serialized via Avro using HTTP as transport?

I'm using Avro as the serialization protocol. My service is ready, every serialization/deserialization works fine in memory.
So now I'd like to test it to see if it works fine after HTTP transport.
I thought it's simple to write a method to test, but after a while, I'm not able to figure it out, here's what I've tried:
Using HttpClient:
String itemIds = "abc123";
System.out.println("itemIds are: " + itemIds + "\n\n\n");
String endpoint = "http://localhost:8080/api/v1/items?itemIds=" + URLEncoder.encode(itemIds, "UTF-8");
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(endpoint);
String USER_AGENT = "Mozilla/5.0";
request.addHeader("User-Agent", USER_AGENT);
request.addHeader("Content-Type", "avro/binary");
HttpResponse response = client.execute(request);
System.out.println("Response Code : "
+ response.getStatusLine().getStatusCode());
byte[] bytes = EntityUtils.toByteArray(response.getEntity());
SearchMaterializationDto deserializedReponse = SearchMaterializationAvroObjectSerializer.deserializeToSearchMaterialization(bytes);
System.out.println(deserializedReponse.toString());
This approach is throwing java.io.EOFException. when executing this line SearchMaterializationDto deserializedReponse = SearchMaterializationAvroObjectSerializer.deserializeToSearchMaterialization(bytes);
Here's my SearchMaterializationDto deserializedReponse = SearchMaterializationAvroObjectSerializer.deserializeToSearchMaterialization(bytes); method:
public static SearchMaterializationDto deserializeToSearchMaterialization(byte[] buffer) {
SearchMaterializationDto searchMaterializationDto = new SearchMaterializationDto();
try {
ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(buffer));
searchMaterializationDto.readExternal(input);
} catch (IOException e) {
throw new RuntimeException(e);
}
return searchMaterializationDto;
}
And here's my SearchMaterializationDto.java class (listed only the invoked method):
#org.apache.avro.specific.AvroGenerated
public class SearchMaterializationDto extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
private static final org.apache.avro.io.DatumReader
READER$ = new org.apache.avro.specific.SpecificDatumReader(SCHEMA$);
#Override public void readExternal(java.io.ObjectInput in)
throws java.io.IOException {
READER$.read(this, SpecificData.getDecoder(in));
}
}
Using Avro Decoder as this example shows:
private static void decoderWay(String endpoint) throws IOException {
byte[] bytes = getBytes(endpoint);
Decoder decoder = DecoderFactory.get().binaryDecoder(bytes, null);
SpecificDatumReader<SearchMaterializationDto> reader = new SpecificDatumReader<SearchMaterializationDto>(SearchMaterializationDto.getClassSchema());
SearchMaterializationDto searchMaterializationDto = reader.read(null, decoder);
}
But it's also throwing EOFException:
Exception in thread "main" java.io.EOFException
at org.apache.avro.io.BinaryDecoder.ensureBounds(BinaryDecoder.java:473)
at org.apache.avro.io.BinaryDecoder.readLong(BinaryDecoder.java:160)
at org.apache.avro.io.BinaryDecoder.doReadItemCount(BinaryDecoder.java:363)
at org.apache.avro.io.BinaryDecoder.readMapStart(BinaryDecoder.java:408)
at org.apache.avro.io.ValidatingDecoder.readMapStart(ValidatingDecoder.java:211)
at org.apache.avro.generic.GenericDatumReader.readMap(GenericDatumReader.java:308)
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:177)
at org.apache.avro.specific.SpecificDatumReader.readField(SpecificDatumReader.java:116)
at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:230)
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:174)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:152)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:144)
It turns out to be my serialization/deserilization code problem. I've changed it to the following and it works:
public static byte[] serializeSearchMaterializationToByteArray(SearchMaterializationDto searchMaterializationDto) {
return avroSerialize(SearchMaterializationDto.class, searchMaterializationDto);
}
public static <T> byte[] avroSerialize(Class<T> clazz, Object object) {
byte[] ret = null;
try {
if (object == null || !(object instanceof SpecificRecord)) {
return null;
}
T record = (T) object;
ByteArrayOutputStream out = new ByteArrayOutputStream();
Encoder e = EncoderFactory.get().directBinaryEncoder(out, null);
SpecificDatumWriter<T> w = new SpecificDatumWriter<T>(clazz);
w.write(record, e);
e.flush();
ret = out.toByteArray();
} catch (IOException e) {
}
return ret;
}
public static SearchMaterializationDto deserializeToSearchMaterialization(byte[] avroBytes) {
return avroDeserialize(avroBytes, SearchMaterializationDto.class, SearchMaterializationDto.getClassSchema());
}
public static <T> T avroDeserialize(byte[] avroBytes, Class<T> clazz, Schema schema) {
T ret = null;
try {
ByteArrayInputStream in = new ByteArrayInputStream(avroBytes);
Decoder d = DecoderFactory.get().directBinaryDecoder(in, null);
SpecificDatumReader<T> reader = new SpecificDatumReader<T>(clazz);
ret = reader.read(null, d);
} catch (IOException e) {
}
return ret;
}

How to serialize and deserialize a RenderedImage as a text string?

I want to serialize a RenderImage as a text string so that I can java a Jason-like file with some fields (Name, Date, Photo).
I would like to use
String s = String.format("%s:%s,%s:%s,%:%s",
"name", my_name,
"date", date,
"photo", someFunctionToGenerateAStringForTheImage(RenderedImage));
And save s to a file.
Currently, I am using this:
public static byte[] imageToByteArray(RenderedImage img) {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
ImageIO.write(img, "png", out);
out.flush();
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
And I call it as such:
String imageAsString =new String(Util.imageToByteArray(post.getImage()));
I deserialize the strings using the following function:
public static RenderedImage byteArrayToImage(byte[] bytes) {
try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) {
return ImageIO.read(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Thus I call it as such byteArrayToImage(imageAsString.getBytes());
Unfortunately, this approach is not working, the objects produced aren't the same... I would like to it using a String.format because my code is much more complex and full of recursive calls, so I want the simplest way of achieving this.
What can you recommend me?
You can try using Data URL:
public static String imageToDataUrl(RenderedImage img) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try {
ImageIO.write(img, "png", bytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
String data = DatatypeConverter.printBase64Binary(bytes.toByteArray()),
//proper data url format
dataUrl = "data:image/png;base64," + data;
return dataUrl;
}
And to deserialise:
public static RenderedImage dataUrlToImage(String dataUrl) {
String data = dataUrl.substring(dataUrl.indexOf(',')+1);
byte[] bytes = DatatypeConverter.parseBase64Binary(data);
try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) {
return ImageIO.read(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Create class
class MyImage {
String name;
Date date;
String photo;
}
and use any json lib, for example GSON:
String s = new GSON.toJson(myImage).replace('{'}.replace{'}');
MyImage myImage = new GSON.fromJson("{"+s+"}", MyImage.class);
Update:
if you have problem with serialization image try to use:
String s = new String(utf8Bytes, "UTF8");
byte[] utf8Bytes = original.getBytes("UTF8");
instead of
String s = new String(utf8Bytes);
byte[] defaultBytes = original.getBytes();

Categories

Resources