2

gson を使用して json 文字列をオブジェクトに変換しようとしています。

以下に非常に簡単な例を示します。これは実行されますが、結果の回答は空です。つまり、Answer オブジェクトのテキスト フィールドが空です。

import com.google.gson.*;

public class Meow {

    public static void main(String[] args) throws Exception{

        Gson gson = new Gson();
        String jsonOutput = "[{\"answer\":{\"text\":\"text1\"}},{\"answer\":{\"text\":\"text2\"}} ]";

        Answer[] a = gson.fromJson(jsonOutput, Answer[].class);

        for(Answer i:a) {
          System.out.println(i.text);
        }       
    }

    public class Answer {

        public String text;

        public Answer(String text) {
            super();
            this.text=text;
        }

        public String toString(){
            return text;
        }

        public void setText(String a){
            this.text=a;
        }
    }

}
4

1 に答える 1

5

JSON がクラスと一致しないためです。

現在の JSON はオブジェクトの配列であり、それぞれがanswerフィールドとしてオブジェクトを含んでいます。

JSON は、次のようにする必要があります。

String jsonOutput = "[{\"text\":\"text1\"},{\"text\":\"text2\"}]";

コメントから追加する編集:

出力を変更できない場合は、「ラッパー」が必要です。何かのようなもの:

public class AnswerWrapper {
    public Answer answer;

    // etc
}

そして、それらの配列を使用します。これが、JSON がマップされるものです。Answerそれらをオブジェクトとして見ることはできません。なぜなら、そうではないからです。

追加するもう 1 つの編集:その他のオプションは、クラスのカスタム デシリアライザーを作成することです。これを行うべきかどうかについては少し混乱していますが、うまくいきます。私がそう言う理由は、オブジェクトの配列ではないAnswerJSON を持っているが、それを望んでいるからです。何が起こっているのか理解していないと混乱する可能性があるため、本番コードでこれに出くわしたらイライラすると思います。

その警告が言われているので、カスタムJsonDeserializerを作成して使用できますGsonBuilder

class AnswerDeserializer implements JsonDeserializer<Answer> {

    public Answer deserialize(JsonElement je, Type type, 
                              JsonDeserializationContext jdc) 
                                   throws JsonParseException {

        return new Answer(je.getAsJsonObject().get("answer")
                            .getAsJsonObject().get("text").getAsString());
    }

}

次に、コードは次のようになります。

public static void main(String[] args) throws Exception{

    String jsonOutput = "[{\"answer\":{\"text\":\"text1\"}},{\"answer\":{\"text\":\"text2\"}} ]";

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Answer.class, new AnswerDeserializer());

    Gson gson = gsonBuilder.create();

    Answer[] a = gson.fromJson(jsonOutput, Answer[].class);

    for(Answer i:a) {
        System.out.println(i.text);
    }       
}

それが私で、JSONが必要なものではなく、GSONを使用して直接シリアライズ/デシリアライズしたい場合Answer、詳細を隠すラッパーとしてクラスを作成します。

/**
 *  Due to how our JSON is being provided we created an inner
 *  class. 
 **/ 
public class Answer {

    private RealAnswer answer;

    private class RealAnswer {

        public String text;
    }

    ...
}

Answerprivate にアクセスするための public getter/setter を使用しRealAnswerます。次の人にとっては、よりクリーンで理解しやすいように思えます。

于 2012-12-14T05:55:30.970 に答える