2017-05-12 7 views
1

Gsonを使用して、サーバからPOJOオブジェクトへの応答JSON文字列を解析しようとしています。以下は私のJSONです:文字列でエンコードされた内部JSON文書のGson解析エラー

{ 
    "user":{ 
     "id":"859adb60-4a47-4e1b-8f40-10480bfc33ec", 
     "createdAt":"2017-05-11T07:52:43.661Z", 
     "updatedAt":"2017-05-11T07:52:43.786Z", 
     "version":"AAAAAAA0GXQ=", 
     "deleted":false, 
     "userName":null, 
     "bucketId":"7c2b3ce4-ac5d-4e6a-a6c1-d6316c01fcfb", 
     "userEmailId":"[email protected]", 
     "signupType":"Custom", 
     "userAvatar":null, 
     "userPin":"$2a$10$9TCIqHrE6jDZMr0lhHRddeC7kU.Ob6s8o8zG3ahsmaAMBNi5Gkvwy", 
     "verified":true, 
     "verifyHash":"IpkzqvjHGb6nbdxxkvmgLiPJRSRhUJ6wMOO3V7Gz5ispOlpLPtdGMTkldzOwHp3Q", 
     "thirdPartyToken":null, 
     "loginAgent":null, 
     "isDataSetUp":false 
    }, 
    "colloboratedChildren":[ 

    ], 
    "invitations":[ 
     { 
     "id":"4892167b-bc6a-47e5-bb30-1785b5643edc", 
     "createdAt":"2017-05-11T07:52:06.019Z", 
     "updatedAt":"2017-05-11T07:52:06.019Z", 
     "version":"AAAAAAA0GWY=", 
     "deleted":false, 
     "inviterId":"9d00f972-e66d-400b-b332-f0b873a8b1fd", 
     "inviterEmail":"[email protected]", 
     "inviteeId":null, 
     "inviteeEmail":"[email protected]", 
     "inviteData":"{\"821e63e7-457e-401f-b071-abacd51bcbad\":[\"B690E26C-BA39-45E3-BB34-CF6EABB666F7\"]}" 
     } 
    ], 
    "authToken":"bQYng6AAeCp9HlR1rCZeOCbFUm1LaRfVzcqTWpgXiLul3tFj7Y4hKr997V6hvl6d" 
} 

ここは私のPOJOクラスです。

@Getter 
@Setter 
public class LoginResponse { 

    User user; 
    ArrayList<ColloboratedChildren> colloboratedChildren; 
    ArrayList<InvitationResponse> invitations; 
    String authToken; 

} 

@Getter 
@Setter 
public class User extends BucketAzureModel { 

    private String signupType; 
    private String userAvatar; 
    private String userEmailId; 
    private String userName; 
    private String userPin; 


} 

@Getter 
@Setter 
ColloboratedChildren {} 

public class InvitationResponse { 

    String id; 
    String createdAt; 
    String updatedAt; 
    String version; 
    boolean deleted; 
    String inviterId; 
    String inviterEmail; 
    String inviteeId; 
    String inviteeEmail; 
    Map<String, ArrayList<String>> inviteData; 

} 

のPOJOにJSONに変換されたコード:私はGsonは{を期待していることを理解し

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at path $.invitations[0].inviteData 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220) 
at com.google.gson.Gson.fromJson(Gson.java:887) 
at com.google.gson.Gson.fromJson(Gson.java:952) 
at com.google.gson.Gson.fromJson(Gson.java:925) 
at com.microsoft.windowsazure.mobileservices.table.serialization.JsonEntityParser.parseResults(JsonEntityParser.java:64) 

エラーから:ここで

JsonEntityParser.parseResults(jsonElement, gsonBuilder.create(), concreteClass); 

は、私が直面していますエラーですここには"がありますが、inviteDataMap<String, ArrayList<String>>を作成する方法を正確に理解していません。私は実際に着信JSONを解析するために私のPOJOをどのように定義するのかは分かりません。私はJSONの形式を変更することはできませんので、私はこの形式のみを守らなければなりません。どんな助けでも本当に感謝しています。

+0

重複している可能性があります[「BEGIN_OBJECTが必要ですが、1行目の列1でSTRINGでした」](http://stackoverflow.com/questions/28418662/expected-begin-object-but-was-string-at-line-1-列1) –

+1

@ user7790438いいえ、それはその複製ではありません。私たちのポスターは、エラーメッセージの意味を知っていますが、GSONに自分が望むことをする方法を知らないのです。非常に異なる質問です。 – ajb

答えて

1
に再びこの文字列値を変更するために持っている他のそのJSONの提供者である場合にJSONレスポンスを変更する必要があります

あなたが扱っているレスポンスが何であれ設計されていれば、Gsonはそれを動作させることができます:Gsonは@JsonAdapterをサポートしており、アドホック(デ)シリアライゼーションを使用できます。

あなたはロンボクを使用するように見えるが、限り、私はロンボクとGsonは(デ)シリアライズ時にデフォルトでフィールドを使用して使用していないとして、あなたはinviteDataフィールド注釈を付けることができます。

final class LoginResponse { 

    final List<InvitationResponse> invitations = null; 

} 
final class InvitationResponse { 

    @JsonAdapter(FromString.class) 
    final Map<String, List<String>> inviteData = null; 

} 

FromStringタイプのアダプタ工場は非常に単純です:

final class FromString 
     implements TypeAdapterFactory { 

    // Gson can instantiate it itself 
    private FromString() { 
    } 

    @Override 
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) { 
     // Obtaining the original type adapter for the declared field 
     return new FromStringTypeAdapter<>(gson.getAdapter(typeToken)).nullSafe(); 
    } 

    private static final class FromStringTypeAdapter<T> 
      extends TypeAdapter<T> { 

     private final TypeAdapter<T> typeAdapter; 

     private FromStringTypeAdapter(final TypeAdapter<T> typeAdapter) { 
      this.typeAdapter = typeAdapter; 
     } 

     @Override 
     public void write(final JsonWriter out, final T value) { 
      throw new UnsupportedOperationException(); 
     } 

     @Override 
     public T read(final JsonReader in) 
       throws IOException { 
      // Just read the current value as a string, and delegate the job to the obtained type adapter 
      final String innerJson = in.nextString(); 
      return typeAdapter.fromJson(innerJson); 
     } 

    } 

} 

それだけです。例:

try (final JsonReader jsonReader = getPackageResourceJsonReader(Q43929916.class, "loginResponse.json")) { 
    final LoginResponse loginResponse = gson.fromJson(jsonReader, LoginResponse.class); 
    for (final InvitationResponse invitation : loginResponse.invitations) { 
     System.out.println(invitation.inviteData); 
    } 
} 

出力:

{821e63e7-457e-401fと-B071-abacd51bcbad = [B690E26C-BA39-45E3-BB34-CF6EABB666F7]}

なお、この溶液Gsonは現在、JSONトークン入力から文字列全体を読み取ることしかできないので(つまり、このようなバッファリングでもあまりにも多くのデータが消費されるメモリ内のバッファリングを必要とするため)、大規模な内部JSONでは十分ではありません。より大きな内部JSONを処理するために、https://github.com/google/gson/issues/971に投票して、中間のバッファを必要としない文字列リーダを返すことができます。

0

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:パスで 期待BEGIN_OBJECTしかしだったSTRING $ .invitationsあなたは[0] .inviteData

したがって、このエラー状態タイプMap<String,ArrayList<String>>であるとinviteDataを期待しますが、何返さなっていることは、それはあなたがappropをしなければならないString

"inviteData":"{\"821e63e7-457e-401f-b071-abacd51bcbad\":[\"B690E26C-BA39-45E3-BB34-CF6EABB666F7\"]}" 
      || 
      || 
      || 
      --->This is a String not of type Map<String,ArrayList<String>> 

だ地図ではありませんあなたのPOJOでriate変化、

class InvitationResponse { 

    String id; 
    String createdAt; 
    String updatedAt; 
    String version; 
    boolean deleted; 
    String inviterId; 
    String inviterEmail; 
    String inviteeId; 
    String inviteeEmail; 
    String inviteData; ----> This should be String 
} 

あなたのJSONは以下のようなものになるだろう場合:

"inviteData" : { 
       "someKey" : [ "SomeValue1","SomeValue2" ] 
      } 

次に、あなたのソリューションが動作していました。このStringだからどちらか、あなたのために役に立たないだろうので、

は今、あなたはあなたが余分な努力がMap<String,ArrayList<String>>

+0

ありがとう、@ Neerajジャインは "応答を変更することはできません。余分な努力をする必要があります。 –

+0

それは私と一緒にたくさん起こる:)、ちょうどこれを達成するために同じgsonオブジェクトを使用します。 –

+0

文字列ではなくマップを使用できるため、追加の文字列の逆シリアル化は必要ありません。 –

関連する問題