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

Gson反序列化报错:Expected BEGIN_OBJECT but was STRING求助

问题排查与解决:Gson反序列化异常

异常原因

异常java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 67 path $.data明确指向:接口返回的JSON中,data字段的值是字符串类型,但你的CheckTokenResp类里将data定义为CmsUser对象类型,Gson无法将字符串直接反序列化为对象,因此抛出错误。

排查步骤

先打印接口返回的完整JSON内容,确认data字段的实际格式:

log.info("接口返回原始JSON: {}", responseEntity.getBody());

大概率会看到类似这样的结构(data是包裹JSON的字符串):

{
  "code": 200,
  "message": "success",
  "data": "{\"id\":123,\"username\":\"test\",\"role\":\"admin\"}"
}

解决方案

根据data字段的实际内容,有两种常见处理方式:

方式一:修改CheckTokenResp适配返回结构

将CheckTokenResp中的data字段类型改为String,再二次反序列化为CmsUser:

  1. 调整CheckTokenResp类:
    public class CheckTokenResp {
        // 保留其他原有字段(如code、message等)
        private String data; // 替换原有的CmsUser类型
    
        // 生成getter、setter方法
    }
    
  2. 修改业务代码:
    Gson gson = new Gson();
    CheckTokenResp response = gson.fromJson(responseEntity.getBody(), CheckTokenResp.class);
    
    if (response == null || response.getData() == null) {
        return null;
    }
    
    // 将字符串类型的data反序列化为CmsUser对象
    CmsUser cmsUser;
    try {
        cmsUser = gson.fromJson(response.getData(), CmsUser.class);
    } catch (JsonSyntaxException e) {
        log.warn("data字段无法反序列化为CmsUser: {}", response.getData(), e);
        return null;
    }
    
    return cmsUser;
    

方式二:自定义Gson反序列化器(无需修改实体类)

如果不想修改CheckTokenResp的data字段类型,可以给Gson注册自定义类型适配器,自动处理字符串转对象的逻辑:

// 创建带自定义适配器的Gson实例
Gson gson = new GsonBuilder()
    .registerTypeAdapter(CmsUser.class, new TypeAdapter<CmsUser>() {
        @Override
        public void write(JsonWriter out, CmsUser value) throws IOException {
            // 序列化时的逻辑,按需实现
            out.value(new Gson().toJson(value));
        }

        @Override
        public CmsUser read(JsonReader in) throws IOException {
            // 反序列化时,判断当前token是字符串还是对象
            if (in.peek() == JsonToken.STRING) {
                // 若为字符串,先读取再反序列化为CmsUser
                String jsonStr = in.nextString();
                return new Gson().fromJson(jsonStr, CmsUser.class);
            } else {
                // 若为对象,直接反序列化
                return new Gson().fromJson(in, CmsUser.class);
            }
        }
    })
    .create();

// 后续反序列化代码保持不变
CheckTokenResp response = gson.fromJson(responseEntity.getBody(), CheckTokenResp.class);

额外优化建议

  • 避免捕获Exception这种宽泛的异常,改为捕获RestClientException,精准处理HTTP请求异常;
  • 增加responseEntity的非空判断,避免请求失败时调用responseEntity.getBody()抛出空指针;
  • 和后端确认接口返回规范,明确data字段的类型是否会在不同场景下变化(比如错误时返回提示字符串),提前兼容这些场景。

内容的提问来源于stack exchange,提问作者Đức Hiếu Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:16:21