1

クライアントとサーバーの2つの単純なアプリケーションがあります。クライアントは(単純なAES)カスタムオブジェクトを暗号化し、TCPソケットを介してバイトとしてサーバーに送信します。サーバーはこれらのバイトを復号化し、次のようにこのオブジェクトを再作成するメソッドを呼び出します。

private static Object getObjectFromBytes(byte[] credentials) throws IOException,      ClassNotFoundException{

    ByteArrayInputStream bis = new ByteArrayInputStream(credentials);
    ObjectInput in = null;
    Object credentialsObj = null;

    try {

        in = new ObjectInputStream(bis);
        credentialsObj = in.readObject(); 

    } finally {
      bis.close();
      in.close();
    }
    return credentialsObj;
}

クライアント側では、このオブジェクトを暗号化するとき、タイプはmds.hm5.client.ITU_Credentialsです。サーバー側では、復号化してオブジェクトに変換し直すときは、である必要がありますmds.hm5.tokenservice.ITU_Credentials。代わりに、次の例外が発生します。

java.lang.ClassNotFoundException: mds.hm5.client.ITU_Credentials

彼は古いクラスパスでこのオブジェクトを探しています。なぜそれが起こっているのですか、そしてどのようにそれを修正する必要がありますか?

追加情報:

このオブジェクトをクライアント側でバイト配列に変換する方法は次のとおりです。

private static byte[] getBytesFromObject(Object credentials) throws IOException{

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutput out = null;
    byte[] newBytes = null;

    try {

      out = new ObjectOutputStream(bos);   
      out.writeObject(credentials);
      newBytes = bos.toByteArray();

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
      out.close();
      bos.close();
    }
    return newBytes;
}   

ジェネリック型を使用する理由Objectは、これらのメソッドを使用して複数の型を変換/暗号化/復号化するためです。それは適切な方法ですか?

4

4 に答える 4

3

クライアント側では、このオブジェクトを暗号化するとき、タイプはmds.hm5.client.ITU_Credentialsです。

これが、シリアル化されたストリームに含まれるものです。

サーバー側では、復号化してオブジェクトに変換し直すときは、mds.hm5.tokenservice.ITU_Credentialsである必要があります。

いいえ、すべきではありません。シリアル化したときと同じである必要があります[特定の魔法の手順を実行した場合を除きますが、明らかに実行していません。それらの魔法のステップがなければ、魔法はなく、何にも接続することmds.hm5.client.ITU_Credentialsはできmds.hm5.tokenservice.ITU_Credentialsません]。同じ名前でパッケージが異なる2つの異なるクラスがあり、それぞれの場所に1つずつあります。それらは同じではありません。

彼は古いクラスパスでこのオブジェクトを探しています。

CLASSPATHとパッケージ名が混同されています。それらは同じものではありません。実際のパッケージ名でこのオブジェクトを探しています。他に何ができるでしょうか?

于 2012-11-20T01:55:37.757 に答える
2

オブジェクト出力ストリームは、クラス自体をシリアル化するのではなく、その状態(フィールド値)のみをシリアル化します。受信者は、そのクラスパスにクラスファイルが必要です。

クラスを転送することも可能です。接続からクラスをロードできるクラスローダーを見つける(または書き込む)必要があります。クラスファイルのURLがある場合は、URLClassloaderを使用できます。そうすれば、クラスをクラスパスに追加する必要はありません。

于 2012-11-19T21:45:07.233 に答える
0

クライアントは、クラスパスにオブジェクトを定義する.classファイルを含める必要があります。あなたがしているのは、クラスではなく、インスタンスのシリアル化/逆シリアル化です。

于 2012-11-19T21:43:31.767 に答える
0

遅いですが、将来誰かに役立つかもしれません:パッケージがクライアント側のエンティティであるオブジェクトメッセージを送信したかったのですが、サーバー側では、このメッセージクラスはエンティティパッケージ内にネストされていなかったため、この例外がスローされました。ばかげているかもしれませんが、私はこれを理解するのに何時間も費やしました。

于 2020-04-28T00:37:06.187 に答える