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

Java 8下用旧版Jackson将JSONObject转为带|的指定YAML格式

解决Jackson 2.7.6生成带|符号的YAML格式问题

方法一:字符串替换(最简单直接)

生成标准YAML后,通过正则匹配替换目标行,快速实现格式修改:

private static String processFilesForYml(JSONObject a_Obj) throws Exception {
    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode jsonNode = objectMapper.readTree(a_Obj.toString());
    String yamlStr = new YAMLMapper().writeValueAsString(jsonNode);
    // 匹配"examples:"开头的行,替换为带|的格式
    return yamlStr.replaceAll("(\\s*)examples:\\n\\s+-", "$1examples: |\\n\\s+-");
}

该方法适合结构固定的场景,仅修改examples字段的输出格式,不改变原数据类型。

方法二:自定义数组序列化器(精准控制)

通过自定义Jackson序列化器,仅对examples字段的数组进行特殊处理,输出带|的块格式:

1. 实现自定义序列化器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.node.JsonArray;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import java.io.IOException;

public class ExamplesArraySerializer extends JsonSerializer<JsonArray> {
    @Override
    public void serialize(JsonArray value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 仅处理名为"examples"的字段,且是YAML输出场景
        if ("examples".equals(gen.getOutputContext().getCurrentName()) && gen instanceof YAMLGenerator) {
            YAMLGenerator yamlGen = (YAMLGenerator) gen;
            yamlGen.writeRaw(" |\n");
            // 获取当前缩进级别,生成对应空格
            int indent = yamlGen.getCurrentIndent();
            StringBuilder indentSb = new StringBuilder();
            for (int i = 0; i < indent; i++) {
                indentSb.append(' ');
            }
            // 遍历数组生成每行的列表项
            for (int i = 0; i < value.size(); i++) {
                yamlGen.writeRaw(indentSb + "- \"" + value.get(i).asText() + "\"\n");
            }
        } else {
            // 其他场景按默认方式序列化数组
            gen.writeStartArray();
            for (int i = 0; i < value.size(); i++) {
                gen.writeString(value.get(i).asText());
            }
            gen.writeEndArray();
        }
    }
}

2. 配置YAMLMapper并使用

private static String processFilesForYml(JSONObject a_Obj) throws Exception {
    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode jsonNode = objectMapper.readTree(a_Obj.toString());

    YAMLMapper yamlMapper = new YAMLMapper();
    // 注册自定义序列化器
    yamlMapper.registerModule(new com.fasterxml.jackson.databind.module.SimpleModule()
            .addSerializer(JsonArray.class, new ExamplesArraySerializer()));

    return yamlMapper.writeValueAsString(jsonNode);
}

此方法精准控制examples字段的输出格式,保持原数组数据类型,其他数组不受影响。

方法三:转换数组为多行字符串(适合无需反序列化场景)

将原examples数组转换为多行字符串,利用Jackson的特性输出块标格式:

private static String processFilesForYml(JSONObject a_Obj) throws Exception {
    // 遍历nlu数组,将examples数组转换为多行字符串
    JSONArray nluArray = a_Obj.getJSONArray("nlu");
    for (int i = 0; i < nluArray.length(); i++) {
        JSONObject nluItem = nluArray.getJSONObject(i);
        if (nluItem.has("examples")) {
            JSONArray examples = nluItem.getJSONArray("examples");
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < examples.length(); j++) {
                sb.append("- \"").append(examples.getString(j)).append("\"\n");
            }
            if (sb.length() > 0) {
                sb.setLength(sb.length() - 1); // 移除最后一个换行符
            }
            nluItem.put("examples", sb.toString());
        }
    }

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode jsonNode = objectMapper.readTree(a_Obj.toString());
    YAMLMapper yamlMapper = new YAMLMapper();
    // 开启多行字符串以块标量输出
    yamlMapper.enable(YAMLGenerator.Feature.WRITE_STRINGS_AS_LITERALS);
    return yamlMapper.writeValueAsString(jsonNode);
}

注意:此方法会将examples的数据类型从数组转为字符串,若后续需要反序列化为数组则不适用,仅适合纯输出场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:35:35