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

使用Google GSON解析JSON请求时遭遇语法错误求助

问题:GSON解析JSON时持续抛出语法错误

我一开始尝试解析这段JSON请求:

{"action":"ProjectCreation", data:{"projectName": "test project"}}

当时没发现语法问题,但GSON抛出了错误:

Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 20 path $

后来我修正了JSON,给data加上双引号,变成:

{"action":"ProjectCreation", "data":{"projectName": "test project"}}

可GSON还是报一模一样的错误。负责解析的代码如下:

private Type type = new TypeToken<Map<String, Object>>(){}.getType();
private String action;
private String responseAction;
private Map<String, String> data;
private Type dataType = new TypeToken<Map<String, String>>(){}.getType();
private Gson gson = new Gson();
private String requestId;
private Client client = new Client("127.0.0.1", 5699);

/**
 * Constructor for this class, sets initial parameters
 * @param request
 * @param _requestId
 */
public ActionThread(String request, String _requestId) {
    System.out.println(request);
    //Parse the request into a map
    Map<String, Object> _request = gson.fromJson(request, type);
    //Give action the correct naming convention
    action = _request.get("action") + "Request";
    responseAction = _request.get("action") + "Response";
    //Parse the data into a map
    String _data = _request.get("data").toString();
    data = gson.fromJson(_data, dataType);
    //Set the request id
    requestId = _requestId;
}

问题根源与解决方案

嘿,其实你的JSON已经没问题了,错误出在解析代码的逻辑上!重点看这两行:

String _data = _request.get("data").toString();
data = gson.fromJson(_data, dataType);

当你用gson.fromJson(request, type)把整个请求解析成Map<String, Object>后,_request.get("data")拿到的已经是GSON自动生成的LinkedTreeMap对象了。这时候你调用toString()方法,得到的字符串根本不是标准JSON格式——它会变成类似{projectName=test project}这样的样子,用的是等号而不是冒号,键也没有双引号,这当然会让GSON再次解析时报语法错误。

两种修复方案任你选:

方案一:直接类型转换(快速修复)

既然data本身就是一个Map,直接把它转成Map<String, String>就行,不用再转成字符串重新解析:

// 替换原来的data解析代码
data = (Map<String, String>) _request.get("data");

⚠️ 注意:如果data里存在非String类型的值,可能会抛出类型转换异常,需要根据你的实际数据结构调整。

方案二:用实体类解析(更规范)

创建一个和请求结构对应的实体类,这样类型更安全,代码也更清晰:

// 定义请求实体类
class ProjectRequest {
    private String action;
    private Map<String, String> data;

    // 生成getter和setter方法
    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public Map<String, String> getData() {
        return data;
    }

    public void setData(Map<String, String> data) {
        this.data = data;
    }
}

然后在构造方法里直接解析到这个类:

public ActionThread(String request, String _requestId) {
    System.out.println(request);
    // 直接解析到实体类
    ProjectRequest _request = gson.fromJson(request, ProjectRequest.class);
    // 后续操作直接用实体类的getter
    action = _request.getAction() + "Request";
    responseAction = _request.getAction() + "Response";
    data = _request.getData();
    requestId = _requestId;
}

这种方式不仅能彻底解决当前的问题,还能让代码更易维护,后续扩展字段也更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:32:21