2015-05-06 75 views
0

成功登錄後,返回從服務器以下JSONObject改造不解析的JSONObject

{"success":true,"message":"Sign in success.","response_data":{"user_id":"24", "email_id":"[email protected]", "secret_code": "You did it!"}} 

我想把response_data信息到我的User對象。我以前做這樣的事情:

String getResponse = jsonObject.getString("response_data"); 

Gson gson = new GsonBuilder() 
     .disableHtmlEscaping() 
     .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) 
     .setPrettyPrinting() 
     .serializeNulls() 
     .create(); 

//All the data in the `response_data` is initialized in `User` 
User user = gson.fromJson(getResponse, User.class); 

現在我試着改造做同樣的:

初始化RestAdapter +接口:

public class ApiClient { 
    private static RetrofitService sRetrofitService; 

    public static RetrofitService getRetrofitApiClient() { 
     if (sRetrofitService == null) { 
      RestAdapter restAdapter = new RestAdapter.Builder() 
        .setLogLevel(RestAdapter.LogLevel.FULL) 
        .setEndpoint("http://xxx.xxx.xxx.xxx/") 
        .build(); 

      sRetrofitService = restAdapter.create(RetrofitService.class); 
     } 

     return sRetrofitService; 
    } 

    public interface RetrofitService { 

     @FormUrlEncoded 
     @POST("/login") 
     public void login(@Field("email_id") String emailId, @Field ("password") String password, 
          Callback <User> callback);                  
    } 
} 

MainActivity:

ApiClient.getRetrofitApiClient().login(email.getText().toString(), password.getText().toString(),  
     new Callback<User>() { 
      @Override 
      public void success(User user, Response response) { 
       User user1 = user; //null 
       Toast.makeText(this, "user is: "+user1.toString(), Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       Toast.makeText(this, "Failed Login", Toast.LENGTH_SHORT).show(); 
      } 
     }); 

用戶:

public class User { 

    private String userId; 
    private String emailId; 
    private String code; 

    public User() { 

    } 

    ... getters 
    ... setters 
} 

Retrofit代碼MainActivity作品,我得到我的log這樣的響應:

{"success":true,"message":"Sign in success.","response_data":{"user_id":"24", "email_id":"[email protected]", "secret_code": "You did it!"}} 

但是它不解析response_data到我User對象。

我該如何解決這個問題?

+0

不,只是一個錯字不幸...我會解決這個問題。感謝您指出這一點 – user2456977

回答

5

你需要創建一個響應對象

public class UserResponse { 
    private User responseData; 
    private String message; 
    private boolean success; 
} 

,改變你的回調返回UserResponse

public interface RetrofitService { 
    @FormUrlEncoded 
    @POST("/login") 
    public void login(@Field("email_id") String emailId, @Field ("password") String password, 
         Callback <UserResponse> callback);                  
} 

注:您還需要創建自定義GSON實例和aplly那到其餘的適配器。

RestAdapter restAdapter = RestAdapter.Builder() 
    .setEndpoint("xxx") 
    .setConverter(new GsonConverter(gson)) 
    .build() 
+0

我只是在改造之前使用Gson。 Gson不會自動整合到改造中嗎?爲什麼我需要聲明一個定製的Gson實例? – user2456977

+0

感謝它的工作! – user2456977

+0

@ user2456977您添加一個轉換器,以便您可以配置諸如字段命名策略之類的選項。如果您正在使用所有的默認設置,則無需這樣做。 – cyroxis

1

首先,

setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); 

你想

setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); 

因爲這是你的字段命名方式。 (例如response_data

然後,您的User類不代表您的服務的答案。創建一個模仿json對象結構的模型類。 (如cyroxis建議)。

最後,您的java成員的命名與您的json字段的命名不一致(例如secret_code vs code在用戶中)。要麼解決此問題,要麼使用@SerializedName將json字段顯式匹配到java字段。

+0

我在改造之前只使用Gson。 Gson不會自動整合到改造中嗎?爲什麼我需要聲明一個定製的Gson實例?感謝您指出不一致之處。我會修復它們 – user2456977

+0

你需要定製你的gson實例,如果你的json字段不匹配你的java字段。通常當json使用snake case和java使用camel case時。 – njzk2

+0

另外,改造不會爲你做任何解釋。你告訴它將這些數據放入一個User實例,它試圖做到這一點。並且您的數據不代表用戶。它表示一個包含字段「response_data」的對象,該字段是用戶的數據。 – njzk2

1

如果你做兩件事情可能解決您的問題:

  1. 更改您的FieldNamingPolicy您GSON Builder以使用LOWER_CASE_WITH_UNDERSCORES
  2. 變化UserResponse和用戶的變量的作用域公共(這可能不是被要求)
+0

我只是在改造之前使用Gson。 Gson不會自動整合到改造中嗎?爲什麼我需要聲明一個定製的Gson實例? – user2456977