6

更新: 今のところマップを使用しています。他のインスタンスに何かを送信したいクラスは、ルーティング文字列であるオブジェクトを送信します。

オブジェクト ストリームを使用し、Java シリアライズ可能を使用してオブジェクトをサーブレットに書き込みます。

最初に文字列を書き、次にオブジェクトを書きます。

サーブレットを受信すると、入力ストリームが ObjectInputStream にラップされます。最初に文字列を読み取り、次にオブジェクトを読み取ります。ルーティング文字列が決定します。

より一般的な方法は、クラス名とその宣言されたメソッドまたは Spring Bean 名を送信することだったかもしれませんが、これで十分でした。


元の質問

基本的な方法は知っているが、手順の詳細が必要な場合。また、Jaxb、RMI、またはEJBを使用できることも知っています...しかし、バイト配列への純粋なシリアル化を使用してこれを行い、それをjvm 1のサーブレット1からjvm 2のサーブレット2に送信することを望みます(同じ2つのアプリサーバーインスタンスLAN、両方の J2EE アプリで設定された同じ Java バージョンと jar)

基本的な手順は (アプローチ 1) :-

  1. Serializable オブジェクトをバイト配列にシリアライズし、文字列を作成します。正確なコードは以下を参照してください

  2. 1 の Base64 出力。Base 64 が必要ですか、またはステップ 2 をスキップできますか?

  3. java.util.URLEncode.encode を使用して文字列をエンコードします

  4. パラメータに名前を付けた後、apache http コンポーネントまたは URL クラスを使用して、サーブレット 1 から 2 に送信します。

  5. サーブレット 2 では、J2EE フレームワークはすでに URLDecoced を行っているため、逆の手順を実行して、パラメーター名に従ってオブジェクトにキャストするだけです。どちらも私たちのアプリなので、型/クラス マッピングへのパラメータ名がわかります。基本的に、JVM 間でオブジェクトを送信する最も高速で便利な方法を探しています。

例:送信するPOJOクラス

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;
    }   

}

* 効用 *

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;
    }

}

****サンプル送信サーブレット***

    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

**** サンプル受信サーブレット ***

    String s = request.getParameter("bean1");
    Bean1 b1 = (Beean1)SerUtl.deserialize(s);
4

4 に答える 4

2

私のために多くの面倒な作業を行うこの Base64 impl を見つけました: http://iharder.net/base64

ユーティリティメソッドがあります:

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

使用:

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"));

type パラメータを使用して、送信するオブジェクトのタイプを受信 JVM に伝えます。各サーブレット/ jsps は最大で 4 つのタイプを受け取りますが、通常は 1 つです。送信する独自​​のアプリとクラスであるため、これは (ネットワーク経由で送信するのと同じように) 迅速でシンプルです。

もう一方の端では、次のように解凍します。

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

それを処理し、結果をエンコードし、結果を送り返します:

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

サーブレット / jsp を呼び出すと、次の結果が得られます。

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

オプションは 0 または Base64.GZIP です

于 2013-07-30T16:34:36.823 に答える
1

JMS も使用できます。Apache Active-MQ は、優れたソリューションの 1 つです。このすべての変換を気にする必要はありません。

  /**
 * @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;
}

私のポイントはdo not write custom code for Serialization, iff it can be avoidedです。

AMQ を使用する場合は、POJO をシリアライズ可能にするだけです。Active-MQ 関数はシリアライゼーションを処理します。

AMQ からの迅速な応答が必要な場合は、 を使用しますvm-transport。これにより、n/w オーバーヘッドが最小限に抑えられます。AMQ 機能のメリットが自動的に得られます。

私はこれを提案しています

  • ネットワーク上で実行されている独自のアプリケーションがあります。
  • オブジェクトを転送するメカニズムが必要です。
  • それを監視する方法も必要になります。

カスタム ソリューションを使用する場合は、上記のことを自分で解決する必要がある場合があります。

于 2013-07-30T10:16:37.420 に答える