4

Javaで書かれたクラスと、C#で書かれた同じクラスがあります。C#クラスをjson文字列にシリアル化し、Java側で逆シリアル化しようとしています。両方のクラスにbyte[]フィールドを追加するまで、すべてうまくいきました。クラスの定義は次のとおりです。C#:

public class RegisterRequest : GenericRequest
{
    public string name { set; get; }
    public string sex { set; get; }
    public string birthday { set; get; }
    public string from { set; get; }
    public string about { set; get; }
    public byte[] image { set; get; }
}

Java:

public class RegisterRequest extends GenericRequest{
    private String name;
    private String sex;
    private String birthday;
    private String from;
    private String about;
    private String pictureUrl;
    private byte[] image;
}

C#側のシリアル化でrequest.ToJson()は、(Json.NET)を使用し、Javaの逆シリアル化では、(GsonRegisterRequest rr = gsonObject.fromJson(msg, RegisterRequest.class);を使用します。msgはjson文字列です)を使用します。

バイト配列に何も送信しなくても、機能します。しかし、配列を埋めると、Java側で例外が発生します。com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 159089

Gsonが識別する配列の始まりを示すものが必要だと思いますが、Json.NETは文字列に追加しませんか?

4

2 に答える 2

3

上記のコメントからの入力の一部を考えると

"image":"/9j/4AAQSkZJRgAB..."

Gsonがどのようにシリアル化するかを見てくださいbyte[]

"a":[96,-76,32,-69,56,81,-39,-44...

答えは明らかです。Gsonはjson配列を使用し、json.netはjson文字列を使用します。どちらかを変更する必要があります。gsonのカスタムシリアライザーを作成するのは簡単です(私は試したことがありませんがbyte[])、おそらく他のツールにも同じことが当てはまります。

于 2012-08-24T18:58:19.970 に答える
-1

わかりました。これはすばらしい質問です。コメントが非常に長くなっているので、先に進んでこれに答えてみます。

まず、問題は、データを読み取るときのパーサーです。バイナリペイロードにだまされて、不正な文字例外が発生します。これは、大きなByteArrayを処理しようとしているが、処理できない文字またはバイトに遭遇したためです(おそらく、バイナリにUTF-8に変換できないバイトがあるためです。また、文字は通常、C#では1バイト、Javaでは2バイトです。

これの原因は2つあると思います。

  1. gsonリーダーは、送信している「byte []」タイプを検出せず、バイナリをUTF-8でエンコードされた文字列として処理します。

  2. JSON.NETバイト配列は、gsonと同じように解釈されないため、JSON.NET互換のデシリアライザーを記述しないと機能しません。

データを確認し続け、エンコーディングを変更してみてください。また、Java用のgsonパーサーを入手して、これよりも詳細に制御できるかどうかを確認する必要があると思います:)

于 2012-08-24T13:06:40.917 に答える