Retrofit获取含其他参数响应中JSON对象列表问题求助
解决Retrofit响应乱码+模型类不匹配问题
兄弟,你的问题其实分两个核心点:响应解码导致的乱码,以及模型类和服务器返回结构不匹配,咱们一步步来解决:
首先搞定乱码问题
你看到的那些乱码字符,90%是因为服务器返回了Gzip压缩的响应,但你的Retrofit客户端没有配置自动解压的逻辑。OkHttp其实自带了处理Gzip的拦截器,直接加上就行:
// 配置支持Gzip的OkHttpClient OkHttpClient okHttpClient = new OkHttpClient.Builder() // 添加Gzip请求拦截器(告诉服务器我们支持压缩) .addInterceptor(new GzipRequestInterceptor()) // 添加Gzip响应拦截器(自动解压压缩的响应) .addNetworkInterceptor(new GzipResponseInterceptor()) .build(); // 初始化Retrofit时用上这个client Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的基础URL") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build();
如果还是有问题,那可能是服务器返回的编码不是UTF-8,你可以在拦截器里强制指定编码:
.addInterceptor(chain -> { Response response = chain.proceed(chain.request()); // 强制用UTF-8解析响应体 String bodyString = response.body().string(); return response.newBuilder() .body(ResponseBody.create(MediaType.parse("application/json; charset=utf-8"), bodyString)) .build(); })
然后修正模型类的结构
这才是你数据解析失败的根本原因!服务器返回的errors是对象数组,每个元素都有code和description字段,但你的RegisterResponseModel里把它定义成了ArrayList<String>,完全不匹配,肯定解析失败。
第一步:创建错误模型类
先定义一个对应错误对象的类:
import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; public class ErrorDetail { @SerializedName("code") @Expose private String code; @SerializedName("description") @Expose private String description; // 生成getter和setter方法 public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
第二步:修正RegisterResponseModel
把原来的ArrayList<String> errors改成List<ErrorDetail> errors,另外注意succeeded字段服务器返回的是布尔值,不是字符串,所以类型要改成Boolean:
import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import java.util.List; public class RegisterResponseModel { @SerializedName("succeeded") @Expose private Boolean succeeded; // 这里用Boolean,不是String! @SerializedName("errors") @Expose private List<ErrorDetail> errors; // 生成getter和setter方法 public Boolean getSucceeded() { return succeeded; } public void setSucceeded(Boolean succeeded) { this.succeeded = succeeded; } public List<ErrorDetail> getErrors() { return errors; } public void setErrors(List<ErrorDetail> errors) { this.errors = errors; } }
最后测试一下
现在你的Retrofit接口不用改(还是Call<RegisterResponseModel> register(@Body UserJSONModel user);),再发起请求的话,应该就能正确解析succeeded=false和对应的错误列表了,乱码也会消失。
内容的提问来源于stack exchange,提问作者Kamil
相关产品推荐
相关产品推荐

