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

Java仅使用GSON实现JSON转HTML功能的问题求解

问题描述

我是Java初学者,想要实现任意JSON文件到HTML文件的转换,除使用GSON解析JSON结构外不依赖任何其他外部库。

示例JSON文件内容

{
    "doctype": "html",
    "language": "en",
    "head": {
        "meta": {
            "charset": "utf-8",
            "viewport": {
                "width": "device-width",
                "initial-scale": 1
            }
        },
        "title": "Page Not Found"
    },
    "body": {
        "h1": "Page Not Found",
        "p": "Sorry, but the page you were trying to view does not exist."
    }
}

预期输出HTML内容

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Page Not Found</title>
    </head>
    <body>
        <h1>Page Not Found</h1>
        <p>Sorry, but the page you were trying to view does not exist.</p>
    </body>
</html>

当前核心转换代码

private static void getJsonData (JsonObject jsonObject) throws IOException {
        jsonObject.keySet().forEach(key ->
        {
            Object value = jsonObject.get(key);

            if (value instanceof JsonObject){
                try {
                    getJsonData((JsonObject) value);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("key " + key + " of value " + value + " is a JsonObject");
            } else if (value instanceof JsonArray){
                try {
                    writeToHtmlFile("<" + key + ">");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("key " + key + " of value " + value + " is a JsonArray");
            } else {
                if (Objects.equals(key, "doctype")) {
                    try {
                        writeToHtmlFile("<!DOCTYPE " + value + ">");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else if (Objects.equals(key, "language")) {
                    try {
                        writeToHtmlFile("<html lang=" + value + ">");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    try {
                        writeToHtmlFile("<" + key + ">");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("key " + key + " of value " + value + " is an entry");
            }
        });
    }

当前错误输出

<!DOCTYPE "html">
<html lang="en">
<charset>
<width>
<initial-scale>
<title>
<h1>
<p>

问题原因
  1. 未区分HTML标签节点和标签属性,比如meta下的charset、viewport是meta标签的属性,不是独立标签,当前逻辑把所有非JsonObject的key都作为独立标签输出,导致出现<charset>这类错误内容
  2. 取值时直接调用JsonPrimitive的toString方法,会自动携带双引号,导致DOCTYPE输出变成<!DOCTYPE "html">不符合规范
  3. 没有处理标签闭合逻辑,普通标签如title、h1输出内容后需要补全闭合标签
  4. 递归顺序错误,先处理子JsonObject再处理当前节点,导致父标签没有正确输出
  5. 没有处理viewport这类复合属性的拼接逻辑,无法生成正确的content属性内容
修复后代码
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import java.io.IOException;
import java.util.Objects;

// 缩进控制,可根据需要调整
private static final String INDENT = "    ";
private static int indentLevel = 0;

private static void writeToHtmlFile(String content) throws IOException {
    // 原有writeToHtmlFile逻辑保留,这里加入缩进输出
    // 示例实现:System.out.print(INDENT.repeat(indentLevel) + content + "\n");
}

private static void convertJsonToHtml(JsonObject json) throws IOException {
    // 先处理根节点特殊属性
    if (json.has("doctype")) {
        writeToHtmlFile("<!DOCTYPE " + json.get("doctype").getAsString() + ">");
        json.remove("doctype");
    }
    if (json.has("language")) {
        writeToHtmlFile("<html lang=\"" + json.get("language").getAsString() + "\">");
        json.remove("language");
    }
    indentLevel++;
    // 遍历根节点剩余标签
    for (String key : json.keySet()) {
        parseNode(key, json.get(key));
    }
    indentLevel--;
    writeToHtmlFile("</html>");
}

private static void parseNode(String key, Object value) throws IOException {
    if (value instanceof JsonObject) {
        JsonObject obj = (JsonObject) value;
        // 处理meta类属性标签
        if (Objects.equals(key, "meta")) {
            for (String attrKey : obj.keySet()) {
                if (obj.get(attrKey) instanceof JsonPrimitive) {
                    // 普通meta属性
                    writeToHtmlFile("<meta " + attrKey + "=\"" + obj.get(attrKey).getAsString() + "\">");
                } else if (obj.get(attrKey) instanceof JsonObject) {
                    // 复合meta属性如viewport
                    JsonObject attrObj = obj.get(attrKey).getAsJsonObject();
                    StringBuilder content = new StringBuilder();
                    for (String k : attrObj.keySet()) {
                        if (content.length() > 0) content.append(", ");
                        content.append(k).append("=").append(attrObj.get(k).getAsString());
                    }
                    writeToHtmlFile("<meta name=\"" + attrKey + "\" content=\"" + content + "\">");
                }
            }
            return;
        }
        // 普通标签节点,先输出开始标签
        writeToHtmlFile("<" + key + ">");
        indentLevel++;
        // 遍历子节点
        for (String childKey : obj.keySet()) {
            parseNode(childKey, obj.get(childKey));
        }
        indentLevel--;
        // 输出闭合标签
        writeToHtmlFile("</" + key + ">");
    } else if (value instanceof JsonPrimitive) {
        // 带内容的普通标签
        String content = value.getAsString();
        writeToHtmlFile("<" + key + ">" + content + "</" + key + ">");
    }
}
使用说明

将原有调用getJsonData的逻辑替换为调用convertJsonToHtml方法即可,逻辑适配当前给出的JSON结构,可根据需要扩展对JsonArray、自定义自闭合标签等场景的支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:39:04