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

Gson解析API返回数据遇MalformedJsonException问题求助

问题:Gson解析API响应时触发JSON格式错误

API返回的响应数据

[{attendanceWithTaskCount=[{InstallerPresent=3.0, TotalTaskDone=8.0}], installersDetails=[{InstallerName=abc- fjd, JobType=erret, TaskCount=6.0}]}]

用于解析的代码

public void installersAttendanceWithTaskCount(String date) {
        TaskController.getInstance(SupervisorTaskSummaryActivity.this).installersAttendanceWithTaskCount(SupervisorTaskSummaryActivity.this, String.valueOf(UserInfo.getUserInfo().getUserId()), date, new IActionCallback() {
            @Override
            public void onSuccess(Object data) {
                try {
                    Gson gson = new Gson();
                    Log.d("API response: ", String.valueOf(data));

                    // Parse the response JSON as an array
                    JsonArray jsonArray = gson.fromJson(String.valueOf(data), JsonArray.class);
                    Log.d("API jsonArray: ", String.valueOf(jsonArray));
                    if (jsonArray.size() > 0) {
                        // Extract the first object from the array
                        JsonObject jsonObject = jsonArray.get(0).getAsJsonObject();

                        // Extract data from "installersDetails" array
                        JsonArray installersArray = jsonObject.getAsJsonArray("installersDetails");

                        if (installersArray.size() > 0) {
                            installerAttendanceWithTaskCountList = new ArrayList<>();

                            for (JsonElement item : installersArray) {
                                if (item.isJsonObject()) {
                                    JsonObject taskSummary = item.getAsJsonObject();
                                    String InstallerName = taskSummary.get("InstallerName").getAsString();

                                    // Replace spaces in the InstallerName field with underscores
                                    //InstallerName = InstallerName.replaceAll(" ", "_");

                                    String JobType = taskSummary.get("JobType").getAsString();
                                    Double TaskCount = taskSummary.get("TaskCount").getAsDouble();

                                    installerAttendanceWithTaskCountModel model = new installerAttendanceWithTaskCountModel(InstallerName, JobType, TaskCount);
                                    installerAttendanceWithTaskCountList.add(model);
                                }
                            }

                            // Creating RecyclerView adapter and setting it
                            installerAttendaceWithTaskCountAdapter adapter = new installerAttendaceWithTaskCountAdapter(SupervisorTaskSummaryActivity.this, installerAttendanceWithTaskCountList);
                            recycler_view.setAdapter(adapter);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(int errorCode, final String errorMessage) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(SupervisorTaskSummaryActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }

错误日志

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 118 path $[0].installersDetails[0].InstallerName
2023-09-27 17:01:03.416 22744-22744 System.err                              W      at com.google.gson.internal.Streams.parse(Streams.java:56)
2023-09-27 17:01:03.416 22744-22744 System.err                              W      at com.google.gson.JsonParser.parse(JsonParser.java:84)
2023-09-27 17:01:03.416 22744-22744 System.err                              W      at com.google.gson.JsonParser.parse(JsonParser.java:59)
2023-09-27 17:01:03.416 22744-22744 System.err                              W      at com.google.gson.JsonParser.parse(JsonParser.java:45)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at .view.SupervisorTaskSummary.SupervisorTaskSummaryActivity$2.onSuccess(SupervisorTaskSummaryActivity.java:135)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at .coreengine.controllers.TaskController$30.onSuccess(TaskController.java:3229)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at .coreengine.controllers.TaskController$30.onSuccess(TaskController.java:3223)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at .coreengine.webapi.CommProvider$1.onResponse(CommProvider.java:118)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at .coreengine.webapi.GsonRequest.deliverResponse(GsonRequest.java:120)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at android.os.Handler.handleCallback(Handler.java:942)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at android.os.Handler.dispatchMessage(Handler.java:99)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at android.os.Looper.loopOnce(Looper.java:223)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at android.os.Looper.loop(Looper.java:324)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at android.app.ActivityThread.main(ActivityThread.java:8385)
2023-09-27 17:01:03.417 22744-22744 System.err                              W      at java.lang.reflect.Method.invoke(Native Method)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:582)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1059)
2023-09-27 17:01:03.418 22744-22744 System.err                              W  Caused by: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 118 path $[0].installersDetails[0].InstallerName
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1573)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:495)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.stream.JsonReader.hasNext(JsonReader.java:418)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:666)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:659)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:667)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:659)
2023-09-27 17:01:03.418 22744-22744 System.err                              W      at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:642)
2023-09-27 17:01:03.419 22744-22744 System.err                              W      at com.google.gson.internal.Streams.parse(Streams.java:44)
2023-09-27 17:01:03.419 22744-22744 System.err                              W      ... 17 more

核心原因

你日志里打印的API响应不是标准JSON格式:标准JSON要求所有键名、字符串值必须用双引号包裹,而当前响应里的attendanceWithTaskCount、InstallerName等键,以及abc- fjd这类字符串值都没有双引号,Gson无法识别这种非标准格式,才会抛出解析错误。

解决方法

方案1:修改API返回标准JSON

让后端返回符合规范的JSON,示例如下:

[{"attendanceWithTaskCount":[{"InstallerPresent":3.0,"TotalTaskDone":8.0}],"installersDetails":[{"InstallerName":"abc- fjd","JobType":"erret","TaskCount":6.0}]}]

修改后你的现有解析代码就能正常工作。

方案2:手动转换非标准格式为标准JSON

如果无法修改API,在解析前对响应字符串做正则替换,给键和字符串值补上双引号:

@Override
public void onSuccess(Object data) {
    try {
        Gson gson = new Gson();
        String rawResponse = String.valueOf(data);
        
        // 给键名加上双引号,匹配类似key=的模式
        rawResponse = rawResponse.replaceAll("(\\w+)=([^\\[,\\]{}]+)", "\"$1\":\"$2\"");
        // 移除数值类型的多余引号(比如3.0不需要双引号)
        rawResponse = rawResponse.replaceAll(":\"(\\d+\\.\\d+)\"", ":$1");
        
        JsonArray jsonArray = gson.fromJson(rawResponse, JsonArray.class);
        // 后续解析逻辑不变...
    } catch (Exception e) {
        e.printStackTrace();
    }
}

注意:这种正则适配是基础版,如果响应里包含特殊字符(比如字符串里的逗号、括号),需要调整正则表达式来覆盖更多场景。

方案3:使用实体类直接映射

定义对应的数据实体类,让Gson直接完成映射,避免手动解析的繁琐:

// 顶层响应实体
public class AttendanceResponse {
    private List<AttendanceTaskCount> attendanceWithTaskCount;
    private List<InstallerDetail> installersDetails;

    // getter、setter方法
    public static class AttendanceTaskCount {
        private double InstallerPresent;
        private double TotalTaskDone;
        // getter、setter
    }

    public static class InstallerDetail {
        private String InstallerName;
        private String JobType;
        private double TaskCount;
        // getter、setter
    }
}

然后在解析时直接转换:

List<AttendanceResponse> responseList = gson.fromJson(rawResponse, new TypeToken<List<AttendanceResponse>>(){}.getType());
// 从responseList中提取数据到你的列表
installerAttendanceWithTaskCountList = new ArrayList<>();
if (!responseList.isEmpty()) {
    for (InstallerDetail detail : responseList.get(0).getInstallersDetails()) {
        installerAttendanceWithTaskCountList.add(new installerAttendanceWithTaskCountModel(
                detail.getInstallerName(),
                detail.getJobType(),
                detail.getTaskCount()
        ));
    }
}
// 后续设置适配器逻辑不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:29:51