java - 改造:根据响应进行 Json 解析器

标签 java android json rest retrofit

我有一个 REST 服务,它的响应可以根据状态进行更改。例如;当我发送请求和响应时可以有两种类型。第一个是这样的

{
  "status": "success",
  "user": {
    "user_id": 3554,
    "full_name": "test",
    "email_address": "test@test1.com",
    "end_date": null
  }
}

第二种就是这样

{
  "status": "failure",
  "reason": "email_taken"
}

根据响应附带的“状态”进行响应。我搜索了这个问题并找到了一些解决方案(自定义转换器,设置自定义转换器等),但我认为这些还不够清楚。有没有类似的解决办法;如果“status”为成功,则转换为 User 模型的 json 响应,否则将 json 响应转换为 FailureModel?

改造依赖:实现“com.squareup.retrofit:retrofit:1.9.0”

如果唯一的解决方案是自定义转换器,请清楚地解释一下,因为我对这个主题非常陌生。

最佳答案

可以使用自定义 json 反序列化器。仅当状态为成功时您才有用户,以防您没有原因。如果您出现状态错误并尝试访问用户其 null。

public class CustomConvertor implements JsonDeserializer<Response> {

    @Override
    public Response deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        Gson gson = new Gson();
        Response response = gson.fromJson(json, Response.class);

        if (response.getStatus().equals("success")) {
            // The full response as a json object
            final JsonObject jsonObject = json.getAsJsonObject();
            // The user attribute in the JSON received
            final JsonElement jsonElement = jsonObject.get("user");

            User user = gson.fromJson(jsonElement, User.class);
            response.setUser(user);
        }else{
            // you could do this
            // not needed as json is deserialized to Response already
            // just for the example
            final JsonObject jsonObject = json.getAsJsonObject();
            String reason = jsonObject.getAsJsonPrimitive("reason").getAsString();
            response.setReason(reason);
        }

        return response;
    }
}

改造部分

GsonBuilder gsonBuilder =new  GsonBuilder();
gsonBuilder.registerTypeAdapter(Response.class, new CustomConvertor());
Gson gson = gsonBuilder.create();
GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(gson);
Retrofit retrofit = new Retrofit.Builder()
         ...// other setups
        .addConverterFactory(gsonConverterFactory).build();

然后

// service is my case
Service service = retrofit.create(Service.class);
// call enqueue in your case.for testing i used mockwebserver
Response response = service.exampleJson().execute().body();
Log.i("User: ","" + response.geUser().getFullname());

如果出现错误

Log.i("Error: ","" + response.getReason());

您可以从http://www.jsonschema2pojo.org/获取您的pojos

波乔的

响应.java

public class Response {

    @SerializedName("status")
    @Expose
    private String status;
    @SerializedName("user")
    @Expose
    private User user;

    @Expose
    @SerializedName("reason")
    private String reason;

    public void setReason(String reason) {
        this.reason = reason;
    }

    public String getReason() {
        return reason;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }    
}

用户.java

public class User {

    @SerializedName("user_id")
    @Expose
    private int userId;
    @SerializedName("full_name")
    @Expose
    private String fullName;
    @SerializedName("email_address")
    @Expose
    private String emailAddress;
    @SerializedName("end_date")
    @Expose
    private Object endDate;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    public Object getEndDate() {
        return endDate;
    }

    public void setEndDate(Object endDate) {
        this.endDate = endDate;
    }
}

另一种方式

Call<Response> auth = .// setup
        auth.enqueue(new Callback<Response>() {
            @Override
            public void onResponse(Call<Response> call, Response<Response> response) {
                if (response.isSuccessful() ) {
                      Response respojo = response.body();
                     if(respojo.getStatus().equals("success"){
                         Log.i("User: ","" + respojo.getUser().getFullname());
                      }else {
                         Log.i("Error: ","" + respojo.getReason());
                      }  
                    }
                } else {
                   response.errorBody(); 

                }
            }

            @Override
            public void onFailure(Call<Response> call, Throwable t) {
                t.printStackTrace();
            }
        });

关于java - 改造:根据响应进行 Json 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52502878/

相关文章:

Android 等待浏览器 Intent 完成

android - 使用gradle构建时已定义的错误

java - 在电话间隙中通过 Ajax 实现 JSON 效果不佳

java - 如何使用javacv识别长宽可变的正方形或矩形?

java - (菜鸟)输出语句的快速帮助

java - 暂停 ScheduledExecutorService

android - 在 android webview 中实现 CSS

java - 尝试将 JSON 字符串转换为 JavaPOJO 时遇到奇怪的问题

java - 无法将 JSON 反序列化为 POJO

java - JSF 项目中的 CDI 功能需要什么?