passing a serialized object - java

In xmlrpc objects need to be serialized before they can be transmitted across a network, so this is what I am trying to do.
addAuthorName = txtAddAuthorName.getText();
int addArticleNumber = Integer.parseInt(txtAddArticleNumber.getText());
newArticle = new Article(addAuthorName, addArticleNumber);
ObjectOutputStream oos;
oos = new ObjectOutputStream(
new ByteArrayOutputStream());
oos.writeObject(newArticle);
Vector<Object> addArticleArglist = new Vector<Object>();
addArticleArglist.addElement(oos);
System.out.println(oos);
// make the call
String callit = ("GetSize.addHash");
articleID = (Integer) client.execute(callit, addArticleArglist);
The problem I am getting is that my program will not accept the outputstream that is contained in the vector the error given is
unsupported Java type: class java.io.ObjectOutputStream

You can only serialize objects that implement the java.io.Serializable interface. Below statement adds ObjectOutputStream to the Vector which doesn't implement that interface.
addArticleArglist.addElement(oos);
I doesn't see any reason why you have to add that to Vector.

The serialization happens automatically. You don't need to undertake further action to serialize the object—just use it as a param, and it will automatically be serialized.

Related

How to put a Bundle inside a blob column in SQLite?

I have this bundle:
Bundle bundle = new Bundle();
bundle.putString("u", mp); // String mp
bundle.putSerializable("m", mealplan); // String[7][6][4][5] mealplan
save.putExtra("b", bundle);
I need to put it inside a blob column but I don't know how exactly.
Bundle objects support Parcels, but the Parcel.marshall() documentation says:
The data you retrieve here must not be placed in any kind of persistent storage (on local disk, across a network, etc). For that, you should use standard serialization or another kind of general serialization mechanism. The Parcel marshalled representation is highly optimized for local IPC, and as such does not attempt to maintain compatibility with data created in different versions of the platform.
The easist serialization mechanism probably is JSON, which is a readable text format.
To create a JSON string, you have to construct a tree of JSONObject/JSONArray objects:
// write
JSONObject json = new JSONObject();
json.put("u", mp);
JSONArray mealplan_json = new JSONArray();
mealplan_json.put(...); // fill arrays recursively
json.put("m", mealplan_json);
String text = json.toString();
// read
JSONObject json = new JSONObject(text);
mp = json.getString("u");
JSONArray mealplan_json = json.getJSONArray("m");
...
If you want to save space with a binary encoding, you have to use serialization, which supports basic types and any object that correctly implements java.io.Serializable:
// write
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(mp);
oos.writeObject(mealplan);
oos.close();
byte[] bytes = bos.toByteArray();
// read
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
mp = (String) ois.readObject();
mealplan = (String[][][][]) ois.readObject();
Please note that this binary serialization does not store any key names ("u", "m"), so you have to ensure that all versions of your app write and read the same objects in the same order.
If you want to have a key/value structure, you have to implement your own helper functions that write values with a separate key string in front, and that read an arbitrary number of key/value pairs into a map.
Alternatively, create your own serializable object that contains the desired elements (and take care that this class stays compatible in future versions of your app):
class MealPlanData implements Serializable {
String u;
String[][][][] mp;
};
If you have only a Bundle object and do not know its structure, you have to handle the keys/values manually:
// write
oos.writeInt(bundle.size());
for (String key : bundle.keySet()) {
Object value = bundle.get(key);
oos.writeObject(key);
oos.writeObject(value);
}
// read
int size = ios.readInt();
Map<String, Object> map = new ArrayMap<String, Object>();
for (int i = 0; i < size; i++) {
String key = (String) ios.readObject();
Object value = ios.readObject();
map.put(key, value);
}

How can I send a hashtable to my clientsocket?

I'm currently working on a small chat program, and for my next step I would like to send a hashtable to my clients, from my server.
However, so far I was using
PrintWriter out = new PrintWriter(socket.getOutputStream());
in my Server class, and
Scanner in = new Scanner(socket.getInputStream());
in my Client class, which were used to transport messages in form of strings from both sockets to the respective other end of the connection.
This does not work for Hashtables anymore, considering they are no primitive datatype.
What would I have to use instead to be able to send my Hashtable fully working to my client?
Since Hashtable implements the java.io.Serializable interface, you can serialize the object and send it over the socket's output stream:
Hashtable table = new Hashtable(); // TODO: avoid raw types
...
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(table);
oos.close();
To read the object in the client, you need to use an ObjectInputStream:
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
Hashtable table = (Hashtable) ois.readObject();

Serializing/deserializing a SIPDIalog

I was trying to serialize and deserialize a gov.nist.javax.sip.stack.SIPDialog object into Cassandra. But the equals comparison on the deserialized object fails when I compare it with the original SIPDialog object I serialized. SO looks like I am missing something here in serialisation. I am using a ByteArraySerializer to read/write the bytes into Cassandra.
//Saving Dialog
MutationBatch mutationBatch = createMutator();
byte[] dialogBytes = SIPDialogEntity.serializeDialog(dialog);
mutationBatch.withRow(SIPDIALOGS, dialogId)
.putColumn("dialog".getBytes(),dialogBytes,null);
mutationBatch.execute();
public static byte[] serializeDialog(SIPDialog dialog) throws IOException {
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bStream);
oos.writeObject(dialog);
oos.close();
byte[] bytes = bStream.toByteArray();
bStream.close();
return bytes;
}
//Reading Dialog
Column<byte[]> result;
result = getKeySpace().prepareQuery(SIPDIALOGS).getKey(dialogId).getColumn("dialog").execute().getResult();
sipDialog = SIPDialogEntity.deserializeDialog(result.getByteArrayValue());
public static SIPDialog deserializeDialog(byte[] byteArrayDialog) throws IOException, ClassNotFoundException {
System.out.println("DEBUG Reading Dialog Bytes:" + byteArrayDialog );
ByteArrayInputStream bStream = new ByteArrayInputStream(byteArrayDialog);
ObjectInputStream ois = new ObjectInputStream(bStream);
SIPDialog dialog = (SIPDialog) ois.readObject();
ois.close();
bStream.close();
return dialog;
}
The SIPDialog class doesn't override the equals method which is why it fails the comparison. Please open an issue in jain sip at http://java.net/jira/browse/JSIP
hmmmm, If SipDialog is your class, you could just skip all the work and use PlayOrm for cassandra ;). Then you don't need to deal with serializing/deserializing.
If it is not your class, I think I will get them to add a way to add 3rd party beans to be converted to an entity much like Guice does in a binding file so it can bind to an entity that can be saved by PlayOrm. IF you open a ticket on PlayOrm with a request, we could get the feature in probably in as little as 1 week.

How do I Serialize Object to Database for Hibernate to read in Java

I'm currently writing a tool to plug into an existing enterprise application that uses Hibernate. My tool at install time needs to write some values into the database where one of the columns is a serialized version of a setting descriptor object. This object has two lists of objects and a few primitive types.
My current approach is to create a ByteArrayOutputStream and an ObjectOutputStream and then write the ObjectOutputStream to the ByteArrayOutputStream, then passing the resulting byte array into the sql with Spring's 1SimpleJdbcTemplate1. My current issue with this approach is that when the enterprise tool pulls my rows it fails to de-serialze the column with the following:
org.springframework.orm.hibernate3.HibernateSystemException: could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize
I feel I may need to serialize the inner objects, but have no clue how to do that and keep everything together.
Ended up solving my own problem. In the hibernate API there is a class called SerializationHelper that has a static function serialize(Serializable obj) which I was able to use to serialize my object and then insert it into the database. Hibernate was then able to read it in the enterprise app.
You can serealize a Java object into bytes and then store it in a BLOB.
Serialize:
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
objOut.writeObject(object);
objOut.close();
byteOut.close();
byte[] bytes = byteOut.toByteArray()
Deserialize:
public <T extends Serializable> T getObject(Class<T> type) throws IOException, ClassNotFoundException{
if(bytes == null){
return null;
}
ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
ObjectInputStream in = new ObjectInputStream(byteIn);
T obj = (T) in.readObject();
in.close();
return obj;
}

java serialized messages dont contain the correct data in socket-client-server model

hello i have a basic client-server system running using java sockets.
my problem is, that an object that i send from the client to the server does not contain the correct data after it has been sent once.
the first time i send it, it arrives with the correct values, but when i send it another time with different values, it still arrives at the server with the same values as the first time. it also happens if i send a completely different instance of that class. it always arrives with the data, which have been sent the very first time.
when i try this with other objects like java.lang.String it seems to work.
the problematic class looks like this:
public class Vector3f implements Serializable {
private static final long serialVersionUID = 2838034155614698213L;
public float x, y, z;
}
i use objectinputstream and objectoutputstream on both the server and the client to send and receive objects.
let me know, if you need any more information about the system.
thanks!
My guess is that you're changing the values of the fields and then retransmitting the same object. The ObjectOutputStream will notice that it's already sent the original object, and just send a reference the second time.
You could avoid this by calling reset() on the ObjectOutputStream - but I'd be tempted to just use separate instances anyway, possibly even making the class immutable. (Public mutable fields are almost never a good idea.)
The best way in case of serialization you should convert the object into a byte array object and then write into the socket.
// Serialize to a file
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("filename.ser"));
out.writeObject(object);
out.close();
// Serialize to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
out = new ObjectOutputStream(bos) ;
out.writeObject(object);
out.close();
// Get the bytes of the serialized object
byte[] buf = bos.toByteArray();
// Deserialize from a file
File file = new File("filename.ser");
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
// Deserialize the object
Object obj = (Object) in.readObject();
in.close();
// Get some byte array data
byte[] bytes = getBytesFromFile(file);
// see Reading a File into a Byte Array for the implementation of this method
// Deserialize from a byte array
in = new ObjectInputStream(new ByteArrayInputStream(bytes));
in.close();

Categories

Resources