8

BasicNameValuePair オブジェクトのリストにカスタム gson シリアライザー/デシリアライザーを実装しようとしています。

ここで部分的なソリューション コード (シリアライゼーション用) を見ました: Gson に基本的な名前と値のペアのリストをシリアライズするにはどうすればよいですか?

ただし、逆シリアル化も実装したかったので、チャンスを試してみましたが、コードは次のとおりです。

package dto;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.message.BasicNameValuePair;


import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;


    public class KeyValuePairSerializer extends TypeAdapter<List<BasicNameValuePair>> {
        @Override
        public void write(JsonWriter out, List<BasicNameValuePair> data) throws IOException {
            out.beginObject();
            for(int i=0; i<data.size();i++){
                out.name(data.get(i).getName());
                out.value(data.get(i).getValue());
            }
            out.endObject();
        }

        @Override
        public List<BasicNameValuePair> read(JsonReader in) throws IOException {
            ArrayList<BasicNameValuePair> list=new ArrayList<BasicNameValuePair>();
             in.beginObject();
             while (in.hasNext()) {
               String key = in.nextName();
               String value = in.nextString();
               list.add(new BasicNameValuePair(key,value));
             }  
             in.endObject();   
             return list;
        }

}

リストを初期化して入力するコード

ArrayList<BasicNameValuePair> postParameters=new ArrayList<BasicNameValuePair>();
postParameters.add(new BasicNameValuePair("some_key","some_value"));

新しい KeyValuePairSerializer クラスを使用するコードは次のとおりです。

        GsonBuilder gsonBuilder= new GsonBuilder();
        gsonBuilder.registerTypeAdapter(KeyValuePairSerializer.class, new KeyValuePairSerializer());
        Gson gson1=gsonBuilder.create();

        //serialization works just fine in the next line
        String jsonUpdate=gson1.toJson(postParameters, KeyValuePairSerializer.class);


        ArrayList<BasicNameValuePair> postParameters2 = new ArrayList<BasicNameValuePair>();
        //postParameters2 = gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class); //? how to cast properly
        //deserialization throws an error, it can't cast from ArrayList<BasicNameValuePair> to KeyValuePairSerializer
        gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class);

問題は、最後に例外がスローされることです。どこに問題があるのか​​ 正確にはわかりませんが、新しいpostParameters2 ArrayListに結果を戻すために最後の行を書き込む方法がまだわかりません。

4

4 に答える 4

9

GSONコレクションの例から適応:

GsonBuilder gsonBuilder= new GsonBuilder();
gsonBuilder.registerTypeAdapter(KeyValuePairSerializer.class, new KeyValuePairSerializer());
Gson gson1=gsonBuilder.create();

Type collectionType = new TypeToken<ArrayList<BasicNameValuePair>>(){}.getType();
ArrayList<BasicNameValuePair> postParameters2 = gson1.fromJson(jsonUpdate, collectionType);
于 2013-03-22T18:31:53.500 に答える
2

registerTypeAdapter は、デシリアライザーではなく、シリアライザーに対してのみ機能するようです。

KeyValuePairSerializerのオーバーライドされた読み取り関数を呼び出す唯一の方法は、結果の値を変数に保存せずに: を呼び出すこと です。関数は正常に処理されますが、ArrayList から KeyValuePairSerializer にキャストできないため、gson クラス内でエラーがスローされます。そして、私はその理由をちょっと理解しています(私が推測する消去)、それを適切に行う方法がわかりません。gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class);

とにかく、この問題を解決するための回避策を見つけました。gson オブジェクトを登録して registerTypeAdapter を呼び出してから使用する代わりに、次のような単純なもので逆シリアルgson1.toJson(Object src, Type typeOfSrc)化を回避gson1.fromJson(String json,Class <T> classOfT)できるようです。

KeyValuePairSerializer k= new KeyValuePairSerializer();
parametersList = (ArrayList<BasicNameValuePair>)k.fromJson(jsonUpdate);
于 2013-03-28T19:49:44.803 に答える
0

JsonObject と NameValuePair はどちらも辞書と同様に動作します。ユース ケースが類似している場合は、一方を他方に変換する必要はないと思います。さらに、JsonObject を使用すると、値をさらに簡単に処理できます (値のペアの配列をループして値を取得するために必要なキーを見つけるのではなく、JsonObject は、キーの名前を直接呼び出すことができる方法で Map と同様に動作します目的のプロパティを返します):

jsonObject.get("your key").getAsString(); (getAsBoolean(), getAsInt(), etc).

あなたの場合、文字列、応答、またはストリームから JsonObject を作成し、マップとしてアクセスします(上記のように):

JsonParser parser = new JsonParser();
JsonObject o = (JsonObject)parser.parse("your json string");
于 2013-03-29T11:19:14.320 に答える
-1

GSON コレクションの例については、このブログをフォローしました。リンクは理解しやすく、実装も簡単です。

public class TimeSerializer implements JsonSerializer<time> {

    /**
     * Implementing the interface JsonSerializer.  
     * Notice that the the interface has a generic
     * type associated with it.  
     * Because of this we do not have ugly casts in our code.
     * {@inheritDoc}
     */
    public JsonElement serialize(
                   final Time time, 
                   final Type type,
                   final JsonSerializationContext jsonSerializationContext) {

        /** 
         * Returning the reference of JsonPremitive 
         * which is nothing but a JSONString.
         * with value in the format "HH:MM"
         */
        return new JsonPrimitive(String.format("%1$02d:%2$02d", 
                              time.getHour(), time.getMinute()));
    }
于 2013-03-29T11:10:39.717 に答える