改造:处理错误 JSON 响应

Retrofit: Handling error JSON response

我的 web 服务器 returns JSON 如果成功(200 状态代码)如下表:

{"success":true,"data":{"user_id":"20","username":"Bob"}}

但如果出现问题(例如,如果在表单中输入的用户名和密码太短),它会 returns JSON 以下面的形式出现(400 status代码):

{"success":true,"errors":{"username":["Username too short"],"password":["Incorrect password","Password too short"]}}

如何处理 Retrofit 中的这两种不同的响应?到目前为止,这是我的代码:

RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(URL)
        .build();

ApiEndpointInterface api = restAdapter.create(ApiEndpointInterface.class);

api.getToken('1', new Callback<DefaultResponse>() {
    @Override
    public void success(DefaultResponse json, Response response) {
        //
    }

    @Override
    public void failure(RetrofitError response) {
        //
    }
});

如何处理这两个结构不同的 JSON 响应?

你应该意识到实际上你发布的两个响应从网络请求的角度来看都是成功的。 失败状态是针对请求失败(网络连接错误、404 等),而不是您 return 尝试在您的后端登录用户后失败。

您需要在 success 方法中解析结果,并从您的应用逻辑角度确定内部结果是否成功。

你当然应该处理 failure()。

如果您从网络服务中获得 JSON,则表示成功。

所以,在你的成功方法中,抓住 JSON 并处理它

例如,从您的 JSON 格式

    @Override
        public void success(DefaultResponse json, Response response) {
           try {
            JSONObject json = new JSONObject(json);
            JSONObject data = json.get("data"); // if no "data" element, it will throw JSONException
        } catch (JSONException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),"username to short",Toast.LENGTH_SHORT).show();
             }
        }

或者您可以使用 GSON 来处理您的 JSON 数据

你需要做两件事。 首先,不要 return 来自服务器的 400。正如其他人所说,您实际上已经从服务器获得了成功的响应,因此您只需要在最后解析错误即可。

您的服务器可以return 一个指示登录成功或失败的标志。 之后,您可以简单地将错误模型添加到您的 DefaultResponse 模型中。像这样

public class DefaultResponse {
        public boolean success;
        public DataModel data;
        public ErrorModel errors;


    public static class DataModel {
        private String user_id;
        private String username;
    }

    public static class ErrorModel { ... }
}

您仍然需要处理服务器以 OK 以外的状态响应的情况,但通常来自服务器的错误响应是简单的纯文本,例如 "bad request".. 您当然可以插入 json 如果您愿意,可以从 RetrofitError.getMessage() 中提取,但 GSON 不会自动为您解析。我希望这有帮助!