Transfer the object to another JVM using serialization - the same version of Java and jars (both running our application)

Update: Now use the map. A class that wants to send something to another instance sends an object, a routing string.

Use stream of objects, use Java serializable to write object to servlet.

First write a String and then an object.

The receiving servlet wraps an input stream around an ObjectInputStream. Reads a line first, and then an object. The routing line decides whether it goes.

A more general way might have been to send the class name and its declared method or Spring bean name, but that was enough for us.


Original question

Know the basic way, but want to detail the steps. I also know that I can use Jaxb or RMI or EJB ... but I would like to do this using pure serialization in bytearray and then encode to send it from servlet 1 in jvm 1 to servlet 2 in jvm 2 (two server instances applications on the same LAN, the same versions of java and jars installed in both J2EE applications)

Basic steps (Approximation 1): -

  • serialize any Serializable into a byte array and create a string. Exact code see below

  • Base64 output 1. Is it required for base 64 or can skip step 2?

  • use java.util.URLEncode.encode to encode a string

  • use apache http components or URL class to send from servlet 1 to 2 after naming parameters

  • on Servlet 2. The J2EE structure already had URLDecoced, now it simply performs the reverse steps and throws the object according to the name param. Since both of our applications, we will know the name of the parameter to display the type / class. Basically looking for the fastest and most convenient way to send objects between JVMs.

Example: POJO class to send

package tst.ser; import java.io.Serializable; public class Bean1 implements Serializable { /** * make it 2 if add something without default handling */ private static final long serialVersionUID = 1L; private String s; public String getS() { return s; } public void setS(String s) { this.s = s; } } 

* Utility *

 package tst.ser; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.URLEncoder; public class SerUtl { public static String serialize(Object o) { String s = null; ObjectOutputStream os = null; try { os = new ObjectOutputStream(new ByteArrayOutputStream()); os.writeObject(o); s = BAse64.encode(os.toByeArray()); //s = URLEncoder.encode(s, "UTF-8");//keep this for sending part } catch (Exception e) { // TODO: logger e.printStackTrace(); return null; } finally { // close OS but is in RAM try { os.close();// not required in RAM } catch (Exception e2) {// TODO: handle exception logger } os = null; } return s; } public static Object deserialize(String s) { Object o = null; ObjectInputStream is = null; try { // do base 64 decode if done in serialize is = new ObjectInputStream(new ByteArrayInputStream( Base64.decode(s))); o = is.readObject(); } catch (Exception e) { // TODO: logger e.printStackTrace(); return null; } finally { // close OS but is in RAM try { is.close();// not required in RAM } catch (Exception e2) {// TODO: handle exception logger } is = null; } return o; } } 

**** send servlet ***

  Bean1 b = new Bean1(); b.setS("asdd"); String s = SerUtl.serialize(b); //do UrlEncode.encode here if sending lib does not. HttpParam p = new HttpParam ("bean1", s); //http components send obj 

**** receiving servlet ***

  String s = request.getParameter("bean1"); Bean1 b1 = (Beean1)SerUtl.deserialize(s); 
+6
source share
4 answers

You do not need to convert to string. You can send binary data directly to the servlet, for example by creating an ObjectOutputStream on top of the HttpUrlConnection of the output stream. Set the POST request method.

The servlet that processes the message can be deserialized from an ObjectStream created from the HttpServletRequest ServletInputStream .

I would recommend JAXB anytime for binary serialization. This framework is not only great for collaboration, but also speeds up development and creates more reliable solutions.

The benefits I see are the best tool, type safety, and code generation, keeping your features open so that you can call your code from a different version or in a different language and simplify debugging. Don't underestimate the cost of fixing errors caused by accidentally sending the wrong type or double-escaped data to the servlet. I would expect the performance benefits to be too small to compensate for this.

+3
source

Serialize any Serializable with a byte array

Yes.

and enter the line.

No.

For exact statements, see below.

 os = new ObjectOutputStream(new ByteArrayOutputStream()); os.writeObject(o); s = os.toString(); // s = Base64.encode(s);//Need this some base 64 impl like Apache ? s = URLEncoder.encode(s, "UTF-8"); 

These statements do not even do what you have described, which is wrong in any case. OutputStream.toString() does not turn bytes into strings, it just returns a unique identifier for the object.

Base64 output with number 1.

The base64 output should use a byte array as input, not a string. A string is not a container for binary data. See the corrected code below.

 ByteArrayOutputStream baos = new ByteArrayOutputStream(); os = new ObjectOutputStream(baos); os.writeObject(o); os.close(); s = Base64.encode(baos.toByeArray()); // adjust to suit your API s = URLEncoder.encode(s, "UTF-8"); 

This at least fulfills your task.

Is base 64 required or can skip step 2?

If you want String, you must somehow encode it.

Use java.util.URLEncode.encode to encode a string

This is only necessary if you send it as a GET or POST parameter.

Use apache http components or URL class to send from servlet 1 to 2 after naming

Yes.

In Servlet 2, the J2EE structure already had URLDecoded, now it simply performs the reverse steps and throws the object according to the parameter name.

Yes, but remember to go directly from the base64 encoded string to an array of bytes, without an intermediate string.

Basically looking for the fastest and most convenient way to send objects between JVMs.

These goals are not always compatible. The most convenient these days are probably XML or JSON, but I doubt they are faster than serialization.

os = null;

Setting links that are about to go out of scope to null is pointless.

HttpParam p = new HttpParam ("bean1", s);

It is possible that HttpParam is doing URLEncoding for you. Check this.

+7
source

Found this Base64 impl, which does a lot of hard work for me: http://iharder.net/base64

Utilities:

  String encodeObject(java.io.Serializable serializableObject, int options ) Object decodeToObject(String encodedObject, int options, final ClassLoader loader ) 

Using:

 try { String dat = Base64.encodeObject(srlzblObj, options); StringBuilder data = new StringBuilder().append("type="); data.append(appObjTyp).append("&obj=").append(java.net.URLEncoder.encode(dat, "UTF-8")); 

Use the type parameter to tell the receiving JVM which type of object I am sending. Each servlet / jsps in most cases receives 4 types, usually 1. Again, since its own application and the classes that we send, it is fast (as when sending over the network) and simple.

At the other end, unzip it:

  String objData = request.getParameter("obj"); Object obj = Base64.decodeToObject(objData, options, null); 

Process it, encode the result, send the result back:

  reply = Base64.encodeObject(result, options); out.print("rsp=" + reply); 

The servlet / jsp call gets the result:

  if (reply != null && reply.length() > 4) { String objDataFromServletParam = reply.substring(4); Object obj = Base64.decodeToObject(objDataFromServletParam, options, null); 

can be 0 or Base64.GZIP

+2
source

You can also use JMS. Apache Active-MQ is one of the best solutions. You do not have to worry about all this conversion.

  /** * @param objectToQueue * @throws JMSException */ public void sendMessage(Serializable objectToQueue) throws JMSException { ObjectMessage message = session.createObjectMessage(); message.setObject(objectToQueue); producerForQueue.send(message); } /** * @param objectToQueue * @throws JMSException */ public Serializable receiveMessage() throws JMSException { Message message = consumerForQueue.receive(timeout); if (message instanceof ObjectMessage) { ObjectMessage objMsg = (ObjectMessage) message; Serializable sobject = objMsg.getObject(); return sobject; } return null; } 

My point is do not write custom code for Serialization, iff it can be avoided .

When you use AMQ, all you have to do is make your POJO serializable. Active-MQ features take care of serialization.

If you need a quick AMQ answer, use vm-transport . This minimizes overhead. You will automatically receive the benefits of AMQ.

I suggest this because

  • You have your own applications running on the network.
  • You need a mechanism to transfer objects.
  • You will also need the ability to control it.

If you go to order, you may have to solve the above things.

+1
source

Source: https://habr.com/ru/post/950013/


All Articles