改造不解析 JSONObject
Retrofit not parsing JSONObject
从服务器成功登录returns以下JSONObject
:
{"success":true,"message":"Sign in success.","response_data":{"user_id":"24", "email_id":"user@gmail.com", "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);
}
}
主要活动:
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
}
MainActivity
中的 Retrofit
代码有效,我在 log
中收到此响应:
{"success":true,"message":"Sign in success.","response_data":{"user_id":"24", "email_id":"user@gmail.com", "secret_code": "You did it!"}}
但是它没有将 response_data
解析为我的 User
对象。
我该如何解决这个问题?
您需要创建一个响应对象
public class UserResponse {
private User responseData;
private String message;
private boolean success;
}
并将您的回调更改为 return UserResponse
public interface RetrofitService {
@FormUrlEncoded
@POST("/login")
public void login(@Field("email_id") String emailId, @Field ("password") String password,
Callback <UserResponse> callback);
}
注意:您还需要创建自定义 Gson 实例并将其应用到其余适配器。
RestAdapter restAdapter = RestAdapter.Builder()
.setEndpoint("xxx")
.setConverter(new GsonConverter(gson))
.build()
首先,
setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE);
你想要
setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
因为这就是您的字段的命名方式。 (例如 response_data
)
那么,您的User
class并不代表您服务的答复。创建一个模仿 json 对象结构的模型 class。 (如 cyroxis 所建议)。
最后,java 成员的命名与 json 字段的命名不一致(例如 secret_code
与用户中的 code
)。要么解决这个问题,要么使用 @SerializedName
将 json 字段显式匹配到 java 字段。
如果你做两件事可能会解决你的问题:
- 更改 GSON Builder 上的 FieldNamingPolicy 以使用 LOWER_CASE_WITH_UNDERSCORES
- 将 UserResponse 和 User 中的变量范围更改为 public(这可能不是必需的)
从服务器成功登录returns以下JSONObject
:
{"success":true,"message":"Sign in success.","response_data":{"user_id":"24", "email_id":"user@gmail.com", "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);
}
}
主要活动:
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
}
MainActivity
中的 Retrofit
代码有效,我在 log
中收到此响应:
{"success":true,"message":"Sign in success.","response_data":{"user_id":"24", "email_id":"user@gmail.com", "secret_code": "You did it!"}}
但是它没有将 response_data
解析为我的 User
对象。
我该如何解决这个问题?
您需要创建一个响应对象
public class UserResponse {
private User responseData;
private String message;
private boolean success;
}
并将您的回调更改为 return UserResponse
public interface RetrofitService {
@FormUrlEncoded
@POST("/login")
public void login(@Field("email_id") String emailId, @Field ("password") String password,
Callback <UserResponse> callback);
}
注意:您还需要创建自定义 Gson 实例并将其应用到其余适配器。
RestAdapter restAdapter = RestAdapter.Builder()
.setEndpoint("xxx")
.setConverter(new GsonConverter(gson))
.build()
首先,
setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE);
你想要
setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
因为这就是您的字段的命名方式。 (例如 response_data
)
那么,您的User
class并不代表您服务的答复。创建一个模仿 json 对象结构的模型 class。 (如 cyroxis 所建议)。
最后,java 成员的命名与 json 字段的命名不一致(例如 secret_code
与用户中的 code
)。要么解决这个问题,要么使用 @SerializedName
将 json 字段显式匹配到 java 字段。
如果你做两件事可能会解决你的问题:
- 更改 GSON Builder 上的 FieldNamingPolicy 以使用 LOWER_CASE_WITH_UNDERSCORES
- 将 UserResponse 和 User 中的变量范围更改为 public(这可能不是必需的)