如何使用Gson反序列化值为String或Object类型的同名字段
解决方案
你当前遇到的是JSON字段多类型兼容问题,message字段同时存在字符串、对象两种格式,Gson默认无法自动适配,确实需要通过自定义反序列化器实现兼容,以下是完整实现方案:
实现步骤
1. 编写自定义反序列化器
你可以选择给Response类编写反序列化逻辑,判断message字段的类型分别处理:
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import java.lang.reflect.Type; public class ResponseDeserializer implements JsonDeserializer<Response> { @Override public Response deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { Response response = new Response(); // 解析固定类型的status字段 response.status = json.getAsJsonObject().get("status").getAsString(); JsonElement messageElement = json.getAsJsonObject().get("message"); // 根据message的类型分支处理 if (messageElement.isJsonObject()) { // 对象类型直接解析为Message实例 response.message = context.deserialize(messageElement, Message.class); } else if (messageElement.isJsonPrimitive()) { // 字符串类型按需处理,以下三种方案选其一即可 // 方案1:返回空Message对象 response.message = new Message(); // 方案2:如果需要保存字符串提示,给Message类新增tip字段后赋值 // response.message = new Message(); // response.message.tip = messageElement.getAsString(); // 方案3:直接将message字段设为null // response.message = null; } return response; } }
2. 注册反序列化器到Gson实例
创建Gson对象时注册上面实现的自定义反序列化器:
Gson gson = new GsonBuilder() .registerTypeAdapter(Response.class, new ResponseDeserializer()) .create();
3. 执行解析
原有解析逻辑无需修改,直接用配置好的Gson实例解析即可:
Response[] response = gson.fromJson(jsonString, Response[].class);
可选优化方案
如果需要复用Message的多类型兼容逻辑,也可以单独给Message类编写反序列化器:
public class MessageDeserializer implements JsonDeserializer<Message> { @Override public Message deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (json.isJsonObject()) { return context.deserialize(json, Message.class); } else if (json.isJsonPrimitive()) { Message message = new Message(); // 按需处理字符串内容 // message.tip = json.getAsString(); return message; } return null; } }
注册时改为绑定Message类即可:
Gson gson = new GsonBuilder() .registerTypeAdapter(Message.class, new MessageDeserializer()) .create();
注意事项
- 请给
Response、Message类的字段补充getter/setter方法,或者将字段访问权限改为public,否则Gson无法完成字段赋值。 - 字符串类型
message的处理逻辑可根据业务需求自由调整,不需要存储字符串的话直接返回空对象或null即可。
内容的提问来源于stack exchange,提问作者predator
相关产品推荐
相关产品推荐

