如何让Retrofit在响应无对应key或不符合模型时抛出JSONException?
实现Retrofit在字段缺失/类型不匹配时触发JSON异常的方法
当然可以实现!其实这事儿得从Retrofit搭配的JSON解析器入手——默认大家用的都是Gson,只要给Gson做些严格配置,再配合模型字段的注解,就能达到你要的效果。下面给你一步步拆解:
1. 给模型字段添加必填注解
Gson的@SerializedName注解有个required参数,把它设为true,就能指定这个字段是必须存在的。如果接口返回的JSON里没有这个key,Gson就会抛出JsonSyntaxException(这是JSONException的子类)。
示例模型类:
public class User { // 标记id字段为必填,缺失则抛出异常 @SerializedName(value = "id", required = true) private int userId; // 标记name字段为必填 @SerializedName(value = "name", required = true) private String userName; // 构造函数、Getter/Setter 略 }
2. 配置严格模式的Gson实例
默认Gson对JSON语法的检查比较宽松,比如允许末尾多逗号、类型不匹配时尝试静默转换等。我们需要开启严格模式,确保类型不匹配时也抛出异常:
// Gson 2.10+版本用这个方式开启严格模式 Gson strictGson = new GsonBuilder() .setStrictness(Strictness.STRICT) .create(); // 如果你用的是Gson 2.9及以下版本,替换成setLenient(false) // Gson strictGson = new GsonBuilder() // .setLenient(false) // .create();
3. 将严格Gson实例传给Retrofit
把上面创建的严格Gson实例设置到Retrofit的ConverterFactory里,这样Retrofit就会用这个配置来解析JSON:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://your-api-domain.com/") // 传入自定义的严格Gson实例 .addConverterFactory(GsonConverterFactory.create(strictGson)) .build();
4. 捕获异常
现在当接口返回的JSON出现以下情况时,就会触发异常:
- 标记了
required=true的字段缺失 - 字段类型不匹配(比如接口返回字符串,但模型里定义的是int)
你可以在调用接口时捕获这个异常,比如用try-catch包裹同步调用,或者在异步回调的onFailure里处理:
// 同步调用示例 try { User user = retrofit.create(UserApi.class).getUser().execute().body(); } catch (IOException e) { // 网络异常 } catch (JsonSyntaxException e) { // JSON解析异常(字段缺失/类型不匹配) e.printStackTrace(); }
额外说明
如果想让所有字段默认都是必填,不想每个字段都加@SerializedName(required=true),可以自定义TypeAdapter或者JsonDeserializer来全局校验,但这种方式灵活性稍差,一般更推荐针对需要的字段单独设置required=true,毕竟不是所有接口字段都是必填项。
内容的提问来源于stack exchange,提问作者theapache64
相关产品推荐
相关产品推荐

