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

Mongo插入文档遇CodecConfigurationException:找不到Gson JsonObject编解码器

解决MongoDB插入时的CodecConfigurationException(找不到JsonObject的Codec)

这个错误太常见了——MongoDB Java驱动的默认编解码器只认识自己家的org.bson.Document、基本数据类型,还有标准的集合类型(比如List<Document>),完全不知道怎么处理Gson的JsonObject。从你贴的docObj内容来看,employeelist字段里存的就是Gson的JsonObject数组,这就是触发异常的直接原因。

下面给你几个实用的解决办法,按需选择:


方法1:直接把Gson JsonObject转成Mongo Document(最快捷)

既然Mongo认Document,那我们就把Gson的JsonObject转成Document就行,两者都是键值对结构,转换成本很低。

假设你现在是从jobDetails这个JsonObject里拿到employeelist,可以这么处理:

// 假设jobDetails是你拿到的Gson JsonObject
JsonObject jobDetailsJson = ...;

// 把JsonObject转成Mongo的Document
Document jobDetailsDoc = Document.parse(jobDetailsJson.toString());

// 构建你的docObj时,用转换后的List<Document>作为employeelist的值
Document docObj = new Document()
    .append("files", Arrays.asList(new Document("filename", "newfile2018-04-25_03-32-01")
                                    .append("filedata", new ArrayList<>())
                                    .append("unalloccount", 0)))
    .append("employeelist", jobDetailsDoc.getList("employeelist", Document.class))
    .append("status", "new")
    .append("seq", 0)
    .append("_id", "jobs0");

// 现在插入就不会报错了
collection.insertOne(docObj);

方法2:自定义Codec,让Mongo驱动支持JsonObject(适合频繁转换场景)

如果你的项目里经常需要在Gson JsonObject和Mongo之间转换,可以自定义一个编解码器,注册到Mongo的配置里,这样驱动就能自动处理JsonObject了。

第一步:写自定义Codec类

import com.google.gson.JsonObject;
import com.google.gson.Gson;
import org.bson.Document;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.BsonReader;
import org.bson.BsonWriter;

public class JsonObjectCodec implements Codec<JsonObject> {
    private final Codec<Document> documentCodec;
    private final Gson gson = new Gson();

    public JsonObjectCodec(CodecRegistry registry) {
        this.documentCodec = registry.get(Document.class);
    }

    @Override
    public JsonObject decode(BsonReader reader, DecoderContext decoderContext) {
        // 把Mongo的Document转成Gson JsonObject
        Document doc = documentCodec.decode(reader, decoderContext);
        return gson.fromJson(doc.toJson(), JsonObject.class);
    }

    @Override
    public void encode(BsonWriter writer, JsonObject value, EncoderContext encoderContext) {
        // 把Gson JsonObject转成Mongo的Document再编码
        Document doc = Document.parse(value.toString());
        documentCodec.encode(writer, doc, encoderContext);
    }

    @Override
    public Class<JsonObject> getEncoderClass() {
        return JsonObject.class;
    }
}

第二步:注册Codec到MongoClient

import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoClient;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import com.mongodb.MongoClientSettings;

// 注册自定义Codec
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
    MongoClientSettings.getDefaultCodecRegistry(),
    CodecRegistries.fromCodecs(new JsonObjectCodec(MongoClientSettings.getDefaultCodecRegistry()))
);

// 配置MongoClient
MongoClientSettings settings = MongoClientSettings.builder()
    .codecRegistry(codecRegistry)
    .build();

MongoClient mongoClient = MongoClients.create(settings);

之后你再插入包含JsonObject的文档,驱动就会自动用你写的Codec处理了。


方法3:使用Mongo的POJO支持(最规范的长期方案)

如果你的项目是面向对象的,不如直接用Mongo的POJO编解码支持,这样可以完全避开JsonObject和Document的转换问题,直接操作Java对象。

第一步:定义POJO类

import java.util.List;

public class Job {
    private List<FileDetail> files;
    private List<Employee> employeelist;
    private String status;
    private int seq;
    private String _id;

    // 别忘了写getter和setter,或者用Lombok简化
    public List<FileDetail> getFiles() { return files; }
    public void setFiles(List<FileDetail> files) { this.files = files; }
    public List<Employee> getEmployeelist() { return employeelist; }
    public void setEmployeelist(List<Employee> employeelist) { this.employeelist = employeelist; }
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public int getSeq() { return seq; }
    public void setSeq(int seq) { this.seq = seq; }
    public String getId() { return _id; }
    public void setId(String id) { this._id = id; }
}

class FileDetail {
    private String filename;
    private List<Object> filedata;
    private int unalloccount;

    // getter和setter
    public String getFilename() { return filename; }
    public void setFilename(String filename) { this.filename = filename; }
    public List<Object> getFiledata() { return filedata; }
    public void setFiledata(List<Object> filedata) { this.filedata = filedata; }
    public int getUnalloccount() { return unalloccount; }
    public void setUnalloccount(int unalloccount) { this.unalloccount = unalloccount; }
}

class Employee {
    private String employeeid;
    private int datacount;

    // getter和setter
    public String getEmployeeid() { return employeeid; }
    public void setEmployeeid(String employeeid) { this.employeeid = employeeid; }
    public int getDatacount() { return datacount; }
    public void setDatacount(int datacount) { this.datacount = datacount; }
}

第二步:注册POJO Codec并插入对象

import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoClient;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import com.mongodb.MongoClientSettings;
import org.bson.codecs.pojo.PojoCodecProvider;
import com.google.gson.Gson;

// 注册POJO编解码器
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
    MongoClientSettings.getDefaultCodecRegistry(),
    CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);

MongoClientSettings settings = MongoClientSettings.builder()
    .codecRegistry(pojoCodecRegistry)
    .build();

MongoClient mongoClient = MongoClients.create(settings);

// 把jobDetails的Json转成Job对象
Job job = new Gson().fromJson(jobDetails.toString(), Job.class);
// 设置其他字段比如files、status、seq、_id
job.setFiles(...); // 这里可以直接传List<FileDetail>
job.setStatus("new");
job.setSeq(0);
job.setId("jobs0");

// 直接插入POJO对象
collection.insertOne(job);

小提醒

尽量保持项目里Mongo相关操作的数据类型一致:要么全用Mongo的Document,要么用POJO,避免混合Gson的JsonObject类型,这样能从根源减少这类编解码异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:33:33