ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(reg_be);
oos.flush();
oos.close();
InputStream is = new ByteArrayInputStream(baos.toByteArray());
This code convert Java Object to InputStream and how can I convert InputStream to an Object? I need to convert my Object to an InputStream then I pass it and I want to get my Object back.
In try block you should write:
ObjectInputStream ois = new ObjectInputStream(is);
Object object = ois.readObject();
ObjectInputStream is initialized with another stream, e.g. BufferedInputStream or your input stream is.
ObjectInputStream ois = new ObjectInputStream(is);
Object object = ois.readObject();
Try the following
ObjectInputStream ois = new ObjectInputStream(is);
Object obj = ois .readObject();
ObjectInputStream ois = new ObjectInputStream(is);
Object object = ois.readObject();
As mentioned by #darijan is working fine.
But again we need to do try, catch block for that code, & for blank input stream it will give EOF (End Of File) related error.
So, I am converting it to a string. Then if the string is not empty or null, then only I am converting it to Object using ObjectMapper
Although it's not an efficient approach, I don't need to worry about try-catch, null handling also is done in a string instead of the input stream
String responseStr = IOUtils.toString(is, StandardCharsets.UTF_8.name());
Object object = null;
// is not null or whitespace consisted string
if (StringUtils.isNotBlank(response)) {
object = getJsonFromString(response);
}
// below codes are already used in project (Util classes)
private Object getJsonFromString(String jsonStr) {
if (StringUtils.isEmpty(jsonStr)) {
return new LinkedHashMap<>();
}
ObjectMapper objectMapper = getObjectMapper();
Map<Object, Object> obj = null;
try {
obj = objectMapper.readValue(jsonStr, new TypeReference<Map<Object, Object>>() {
});
} catch (IOException e) {
LOGGER.error("Unable to parse JSON : {}",e)
}
return obj;
}
private ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
return objectMapper;
}
Related
I want to write a class object to the string and then again create an object from it.
I searched on the net but all I found is to write an object to file however I want to write in the string, not on file.
Below is the example of writing to file similarly I want to write in String or similar Object and not in the file.
some_class implements serializable {
...
}
FileOutputStream f = new FileOutputStream(new File("myObjects.txt"));
ObjectOutputStream o = new ObjectOutputStream(f);
// Write objects to file
o.writeObject(object1);
o.close();
f.close();
FileInputStream fi = new FileInputStream(new File("myObjects.txt"));
ObjectInputStream oi = new ObjectInputStream(fi);
// Read objects
some_class object2 = (some_class) oi.readObject();
oi.close();
fi.close();
Please help with the same.
This would be one way:
try
{
// To String
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(object1);
String serializedObject1 = bos.toString();
os.close();
// To Object
ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject1.getBytes());
ObjectInputStream oInputStream = new ObjectInputStream(bis);
YourObject restoredObject1 = (YourObject) oInputStream.readObject();
oInputStream.close();
} catch(Exception ex) {
ex.printStackTrace();
}
I would prefer the Base64 way though.
This would be an example of encoding:
private static String serializableToString( Serializable o ) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
And this is an example of decoding:
private static Object objectFromString(String s) throws IOException, ClassNotFoundException
{
byte [] data = Base64.getDecoder().decode(s);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(data));
Object o = ois.readObject();
ois.close();
return o;
}
the best way to serialize an object to String and vice versa you should convert the object into JSON String and encode into base64. and to get object decode base64 and convert to object using GSON (opensource google provide java library)
class foo{ String name, email;
//setter getter
}
convert Object to base64 JSON
public static String convertToJson(Object o){
String result=new Gson().toJson(o);
return Base64.getEncoder().encodeToString(result);
}
//read base64
public static <T> T convertJsonToObject(String base64Object,Class<T> classOfT){
Gson gson = new Gson();
return gson.fromJson(new InputStreamReader(new ByteArrayInputStream(Base64.getDecoder().decode(base64Object))),classOfT);
}
public static void main(String[] args) {
foo obj=new foo("jhon","jhon#gamil.com");
String json=convertToJson(foo);
System.out.println(json);
foo obj_fromJson=convertJsonToObject(json,foo.class);
System.out.println(obj_fromJson.getName());
}
I have run SAST in my codebase and got some Medium severity alerts in the Checkmarx scan and few of them states 'Unclosed_Objects' . I am not understanding this issue. Any pointers will help me.
This is giving alerts in this section of the code. All the close() methods.
public Object deepCopy(final Object value) throws HibernateException {
try {
// use serialization to create a deep copy
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(value);
oos.flush();
oos.close();
bos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
Object obj = new ObjectInputStream(bais).readObject();
bais.close();
return obj;
} catch (ClassNotFoundException | IOException ex) {
throw new HibernateException(ex);
}
I am trying to serialize custom object which has java.util.set fields using Apache Avro using below code:
final Schema schemaItemImportSchema = ReflectData.get().getSchema(clazz);
final DatumWriter<T> writer = new ReflectDatumWriter<>(clazz);
byte[] data = new byte[0];
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
final Encoder encoder = EncoderFactory.get().jsonEncoder(schema, stream);
datumWriter.write(data, encoder);
encoder.flush();
data = stream.toByteArray();
} catch (final Exception excp) {
log.error(excp);
}
And deSerialization using below code,
final Schema schemaItemImportSchema = ReflectData.get().getSchema(clazz);
final DatumReader<T> reader = new ReflectDatumReader<>(clazz);
Object dataActual = new Object();
try {
final Decoder decoder = DecoderFactory.get().jsonDecoder(schema, new String(data));
dataActual = reader.read(null, decoder);
} catch (final IOException excp) {
log.error(excp);
}
Using above code I am able to serialize successfully with set fields but during de-serialization getting below error,
java.lang.RuntimeException: java.lang.NoSuchMethodException: java.util.Set.<init>()
If I use #AvroIgnore for set fields, both serialization and de-serialization works perfectly.
How can I serialize and deserialize java.util.set fields?
Resolved this issue by changing type to HashSet instead of set.
Referred https://blog.51cto.com/shadowisper/1947979
Here is some part of my code:
This I use to receive JSONObject if it is an JSONObject, if it fails to create a JSONObject of the incoming buffer, then it is an object of class PackageFile
that contains metadata and a byte[].
public JSONObject receiveJSONObject(){
JSONObject json =null;
byte[] headerBytes=null;
ByteBuffer buffer=null;
try{
buffer= ByteBuffer.allocateDirect(2000024);
socketChannel.read(buffer);
buffer.flip();
headerBytes = new byte[buffer.remaining()];
buffer.get(headerBytes);
String jsonString = new String(headerBytes);
json = new JSONObject(jsonString);
return json;
}catch(Exception ex){
if(ex.toString().equals("org.json.JSONException: A JSONObject")){
System.out.println("byte[] is a FilePackage");
getDownloadedFilePackage(buffer);
}else{
ex.printStackTrace();
}
json=null;
}
return json;
}
private boolean getDownloadedFilePackage(ByteBuffer buffer){
FilePackage filePackage=null;
ByteArrayInputStream in=null;
ObjectInputStream obIn=null;
try{
if(buffer!=null){
in = new ByteArrayInputStream(buffer.array()); //Fails,,see: PR1
obIn = new ObjectInputStream(Channels.newInputStream(socketChannel));
filePackage= (FilePackage) obIn.readObject();
fdm.addFilePackageToDownloadingProtocol(filePackage);
in.close();
obIn.close();
return true;
}
}catch(Exception ex){
ex.printStackTrace();
}
return false;
}
PR1: When it fails in = new ByteArrayInputStream(buffer.array());, it gives this exception:
java.lang.UnsupportedOperationException
at java.nio.ByteBuffer.array(ByteBuffer.java:959)
at Client.CommunicationProtocol.getDownloadedFilePackage(CommunicationProtocol.java:115)
at Client.CommunicationProtocol.receiveJSONObject(CommunicationProtocol.java:100)
at Client.OperationManagerNIO.run(OperationManagerNIO.java:19)
at java.lang.Thread.run(Thread.java:745)
This part of the code below send the FilePackage:
public void sendFilePackage(FilePackage filePackage,SocketChannel channel){
ByteArrayOutputStream baos =null;
ObjectOutputStream oos =null;
try{
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(filePackage);
//baos.writeTo(oos);//not used
oos.flush();
channel.write(ByteBuffer.wrap(baos.toByteArray()));
}catch(Exception ex){
ex.printStackTrace();
}
}
Please help me! I can receive any message with JSONObject without any problems, but the problem is when I'm trying to send a class object, it does not work! I have been on this problem for 2 days now, and I can not see straight anymore.
As I said before, the problem is receiving the FilePackage(Class) object, it throws an exception on the first row that handles the incoming buffer from TCP NIO socketChannel.
I have tried to:
Just send FilePackage object - didn't succeed, the problem lays there, - how to send and retrieve a class object via Objectoutputstream and bytearrayoutputstream.
I have a file containing java objects, wrote with this code:
from(somewhere).process(new Processor() {
#Override
public void process(final Exchange exchange) {
...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos);
out.writeObject(myObject);
exchange.getOut().setBody(bos.toByteArray());
}
}).to("file://pathFile");
And now, I want read them fastly. I don't know how can I do that, something like the following code I gess.
from("file://pathFile").convertBodyTo(String.class)
.split(body().tokenize("???")) // How can I tokenize my file ?
.streaming().threads(2)
.process(new Processor() {
#Override
public void process(final Exchange exchange) {
String filePath = (String) exchange.getIn().getHeader(Exchange.FILE_PATH);
File file = new File(filePath);
MyObject myObject = null;
try {
FileInputStream fis = new FileInputStream(file);
InputStream buffer = new BufferedInputStream(fis);
ObjectInput input = new ObjectInputStream(buffer);
Object obj = null;
while ((obj = input.readObject()) != null) {
// Do something
myObject = obj;
}
} catch (Exception e) {
...
} finally {
...
}
exchange.getIn().setBody(myObject);
}
}).to(somewhere);
EDIT: I edit my way to read object. There is still a problem with that code, we can't append to an ObjectOutputStream. That will corrupt the stream. There is a solution [here] for this problem. We can only write the stream header one time.
But If I do that, I wont be able to split and read my file with multiple threads. So can I split or access my file on ObjectOutputStream header ?
you just converted it to a String using convertBodyTo(String.class), therefore you have a String in the body rather than an InputStream....