You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中如何解析自定义统一格式JSON响应数据

问题描述

我在API中定义了一组类,希望请求返回结果格式半统一,为此创建了如下包含3个字段的类:

public class resultDataClass
{
    public Boolean state { get;set; }
    public string message { get; set; }
    public object data { get; set; } // 这个字段会返回不同类型的数据
}

其中第三个字段data会返回不同类的数据,可能是Users类、Department类或其他类,对应的JSON响应示例如下:

一种返回用户列表的响应:

{
"state": true,
"message": " data description",
"data": [
          {
             "id": 1,
             "UserName": "",
             "password": "",
             "email": "",
             "phone": ""
          },
          {
             "id": 2,
             "UserName": "",
             "password": "",
             "email": "",
             "phone": ""
          }
        ]
}

另一种返回其他类型数据的响应:

{
"state": true,
"message": " data description",
"data": [
          {
             "id": 1,
             "title": "",
             "content": "",
             "description": "",
             "image": ""
          },
          {
             "id": 1,
             "title": "",
             "content": "",
             "description": "",
             "image": ""
          }
        ]
}

现在我需要在Android Studio的Java中构建一个统一的响应类来解析这类JSON数据,该如何定义如下ResponseClass中的data字段?

public class ResponseClass {
    public boolean state;
    public String message;
    // 这里该如何定义类似上面API中的object类型字段?
    public List<?> data;

    public boolean isState() {
        return state;
    }

    public String getMessage() {
        return message;
    }
}

我目前编写了针对单个类的请求解析代码,如下:

String myMessage="";
Call<ResponseData> call=api.getPosts(userId);
call.enqueue(new Callback<ResponseData>() {
    @Override
    public void onResponse(@NonNull Call<ResponseData> call, @NonNull Response<ResponseData> response) {
                if(response.isSuccessful()) {

                    if(response.body.isstate)
                        {
                          
                    try {
                        for(int i = 0; i< response.body().getData().size(); i++)
                        {
                            // 这里从目标类中获取数据
                            // 可能是User类或其他类
                            mylist.add(row);
                        }
                        
                        adapter=new MyAdapter(getContext(),mylist);
                        recyclerView.setAdapter(adapter);
                        pd.dismiss();
                    }catch (Exception exception)
                    {
                       
                    }
                } else myMessage=response.body.getmessage();}
                else {
                    
                }
    }

    @Override
    public void onFailure(@NonNull Call<ResponseContentData> call, @NonNull Throwable t) {
        Toast.makeText(getContext(), "message :"+ t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();

    }
});

请问如何修改以支持不同类型的data字段解析?

解决方案

1. 定义泛型响应类

把ResponseClass改成泛型类,这样就能根据不同接口的返回类型,动态指定data的具体类型:

public class Response<T> {
    public boolean state;
    public String message;
    public List<T> data; // 用泛型T替代不确定的类型

    public boolean isState() {
        return state;
    }

    public void setState(boolean state) {
        this.state = state;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }
}

2. 定义对应的数据实体类

针对API返回的不同data类型,分别定义对应的Java实体类:

  • 用户类:
public class User {
    public int id;
    public String UserName;
    public String password;
    public String email;
    public String phone;

    // 可选:添加getter和setter方法
}
  • 内容类:
public class Content {
    public int id;
    public String title;
    public String content;
    public String description;
    public String image;

    // 可选:添加getter和setter方法
}

3. 修改Retrofit接口定义

在你的Retrofit API接口中,根据不同接口的返回类型指定泛型:

public interface ApiService {
    // 获取用户列表的接口,泛型指定为User
    @GET("users")
    Call<Response<User>> getUsers(@Query("userId") int userId);

    // 获取内容列表的接口,泛型指定为Content
    @GET("contents")
    Call<Response<Content>> getContents(@Query("userId") int userId);
}

4. 修改解析代码

调用接口时,根据返回类型直接处理data字段:
比如获取用户列表的场景:

String myMessage = "";
Call<Response<User>> call = api.getUsers(userId);
call.enqueue(new Callback<Response<User>>() {
    @Override
    public void onResponse(@NonNull Call<Response<User>> call, @NonNull Response<Response<User>> response) {
        if (response.isSuccessful() && response.body() != null) {
            if (response.body().isState()) {
                try {
                    List<User> userList = response.body().getData();
                    // 直接使用User类的属性
                    for (User user : userList) {
                        String userName = user.UserName;
                        String email = user.email;
                        // 将数据添加到列表,适配RecyclerView
                        mylist.add(new UserRow(userName, email)); // 假设UserRow是你自定义的列表项模型
                    }
                    adapter = new MyAdapter(getContext(), mylist);
                    recyclerView.setAdapter(adapter);
                    pd.dismiss();
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            } else {
                myMessage = response.body().getMessage();
            }
        }
    }

    @Override
    public void onFailure(@NonNull Call<Response<User>> call, @NonNull Throwable t) {
        Toast.makeText(getContext(), "错误:" + t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
    }
});

如果是获取内容列表,只需要把泛型换成Content即可:

Call<Response<Content>> call = api.getContents(userId);
call.enqueue(new Callback<Response<Content>>() {
    @Override
    public void onResponse(@NonNull Call<Response<Content>> call, @NonNull Response<Response<Content>> response) {
        if (response.isSuccessful() && response.body() != null) {
            if (response.body().isState()) {
                List<Content> contentList = response.body().getData();
                for (Content content : contentList) {
                    String title = content.title;
                    String desc = content.description;
                    // 处理内容数据
                }
                // 更新UI...
            }
        }
    }

    @Override
    public void onFailure(@NonNull Call<Response<Content>> call, @NonNull Throwable t) {
        // 错误处理...
    }
});

额外说明

如果你的JSON解析用的是Gson,Retrofit会自动根据泛型类型完成解析,不需要额外配置。如果遇到复杂的类型转换问题,可以给Gson添加自定义类型适配器,但大部分场景下泛型方案足够解决问题。

内容的提问来源于stack exchange,提问作者San Nasser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:10:01