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

Java Bson库如何将BsonArray等单个BsonValue转换为JSON字符串?

问题

开发MongoDB ChangStream导入AWS Redshift功能时,需要将MongoDB中的复合字段类型(如BsonArray、BsonDocument)转换为JSON字符串。Java Bson库仅支持通过toJson方法将BsonDocument转换为JSON字符串,但BsonArray等其他复合字段类型没有直接的转换方法。

示例代码:

BsonArray bsonArray = new BsonArray();
bsonArray.add(new BsonString("apple"));
bsonArray.add(new BsonString("banana"));
bsonArray.add(new BsonString("orange"));

期望输出:

["apple","banana","orange"]

尝试了以下代码:

BsonArray bsonArray = new BsonArray();
bsonArray.add(new BsonString("apple"));
bsonArray.add(new BsonString("banana"));
bsonArray.add(new BsonString("orange"));

StringWriter stringWriter = new StringWriter();

JsonWriter jsonWriter = new JsonWriter(stringWriter);

jsonWriter.writeStartArray();
for (int i = 0; i < bsonArray.size(); i++) {
    jsonWriter.writeString(bsonArray.get(i).toString());
}
jsonWriter.writeEndArray();
jsonWriter.flush();

String jsonString = stringWriter.toString();

System.out.println("JSON: " + jsonString);

但抛出异常:

Exception in thread "main" org.bson.BsonInvalidOperationException: A StartArray value cannot be written to the root level of a BSON document.
解决方案

方法一:利用CodecRegistry直接编码BsonArray

报错原因是默认的JsonWriter以BSON文档模式工作,不允许根节点为数组。通过配置JsonWriter为JSON输出模式,并利用BsonArrayCodec完成编码,可以正确输出JSON数组:

import org.bson.BsonArray;
import org.bson.BsonString;
import org.bson.codecs.BsonArrayCodec;
import org.bson.codecs.BsonValueCodecProvider;
import org.bson.codecs.EncoderContext;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.json.JsonMode;
import org.bson.json.JsonWriter;
import org.bson.json.JsonWriterSettings;

import java.io.StringWriter;

public class BsonArrayToJson {
    public static void main(String[] args) {
        BsonArray bsonArray = new BsonArray();
        bsonArray.add(new BsonString("apple"));
        bsonArray.add(new BsonString("banana"));
        bsonArray.add(new BsonString("orange"));

        StringWriter stringWriter = new StringWriter();
        // 配置JsonWriter为JSON输出模式
        JsonWriter jsonWriter = new JsonWriter(stringWriter, JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build());
        // 注册BsonValue的Codec
        CodecRegistry registry = CodecRegistries.fromProviders(new BsonValueCodecProvider());
        BsonArrayCodec arrayCodec = registry.get(BsonArray.class);
        // 编码BsonArray到JsonWriter
        arrayCodec.encode(jsonWriter, bsonArray, EncoderContext.builder().build());

        String jsonString = stringWriter.toString();
        System.out.println(jsonString); // 输出 ["apple","banana","orange"]
    }
}

方法二:使用新版本MongoDB Java驱动的toJson方法

如果使用的是MongoDB Java驱动3.8及以上版本,BsonArray继承的BsonValue接口已经提供了toJson()方法,可以直接调用:

BsonArray bsonArray = new BsonArray();
bsonArray.add(new BsonString("apple"));
bsonArray.add(new BsonString("banana"));
bsonArray.add(new BsonString("orange"));

String jsonString = bsonArray.toJson();
System.out.println(jsonString); // 输出 ["apple","banana","orange"]

方法三:临时包裹BsonArray到BsonDocument(兼容旧版本)

如果无法升级驱动,可以将BsonArray放到一个临时的BsonDocument中,调用toJson后再裁剪掉外层的键值对:

BsonArray bsonArray = new BsonArray();
bsonArray.add(new BsonString("apple"));
bsonArray.add(new BsonString("banana"));
bsonArray.add(new BsonString("orange"));

// 用临时键包裹数组
BsonDocument tempDoc = new BsonDocument("temp", bsonArray);
String tempJson = tempDoc.toJson();
// 裁剪掉外层的{"temp": 和 }
String jsonString = tempJson.substring(8, tempJson.length() - 1);
System.out.println(jsonString); // 输出 ["apple","banana","orange"]

内容的提问来源于stack exchange,提问作者冲天炮

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:42:08