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

Quarkus是否原生支持MongoDB GridFS?大文件存储场景咨询

Quarkus + MongoDB GridFS 大文件上传/下载实现方案

核心问题解答

Quarkus的quarkus-mongodb-client扩展原生支持GridFS,它基于官方MongoDB Java驱动,而驱动本身提供了完整的GridFS操作API。Quarkus官方文档未单独针对GridFS做专项说明,但可以直接通过驱动API实现大文件的存储与检索需求,无需依赖Apache Camel。


方案一:纯Quarkus实现(基于MongoDB Client)

1. 添加依赖

在pom.xml中引入MongoDB Client扩展:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-mongodb-client</artifactId>
</dependency>

2. 配置MongoDB连接

在application.properties中配置MongoDB地址与目标数据库:

quarkus.mongodb.connection-string=mongodb://localhost:27017
quarkus.mongodb.database=file-storage

3. 大文件上传接口(Multipart Form)

创建REST接口接收文件与自定义元数据,通过GridFSBucket将文件与元数据绑定存储:

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSUploadOptions;
import jakarta.inject.Inject;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.jboss.resteasy.reactive.PartType;
import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.multipart.FileUpload;
import org.bson.Document;
import org.bson.types.ObjectId;

@Path("/files")
public class FileResource {

    @Inject
    GridFSBucket gridFSBucket; // Quarkus自动注入GridFSBucket实例

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
            @RestForm("file") FileUpload file,
            @RestForm("metadata") @PartType(MediaType.APPLICATION_JSON) Document metadata) {

        // 配置上传参数:附加元数据、自定义分块大小(默认256KB)
        GridFSUploadOptions options = new GridFSUploadOptions()
                .metadata(metadata)
                .chunkSizeBytes(256 * 1024);

        // 上传文件至GridFS,返回文件唯一ID
        ObjectId fileId = gridFSBucket.uploadFromStream(file.fileName(), file.uploadedFile().toFileInputStream(), options);

        return Response.ok(fileId.toHexString()).build();
    }
}

4. 大文件下载接口

通过文件ID检索并返回文件,同时可附带元数据信息:

import com.mongodb.client.gridfs.model.GridFSFile;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Response;
import org.bson.types.ObjectId;
import org.bson.Document;
import java.io.InputStream;

@GET
@Path("/download/{fileId}")
public Response downloadFile(@PathParam("fileId") String fileId) {
    GridFSFile gridFSFile = gridFSBucket.find(new Document("_id", new ObjectId(fileId))).first();
    if (gridFSFile == null) {
        return Response.status(Response.Status.NOT_FOUND).build();
    }

    // 获取文件输入流
    InputStream inputStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());

    // 返回文件,附带下载文件名与元数据
    return Response.ok(inputStream)
            .header("Content-Disposition", "attachment; filename=\"" + gridFSFile.getFilename() + "\"")
            .header("X-File-Metadata", gridFSFile.getMetadata().toJson())
            .build();
}

方案二:Apache Camel Quarkus集成实现

如果倾向于使用Camel的路由能力,可通过quarkus-camel-mongodb-gridfs扩展快速完成集成:

1. 添加依赖

<dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>quarkus-camel-mongodb-gridfs</artifactId>
</dependency>

2. 配置MongoDB连接

同方案一的application.properties配置,额外添加Camel GridFS组件配置:

camel.component.mongodb-gridfs.connection-string=mongodb://localhost:27017
camel.component.mongodb-gridfs.database=file-storage

3. Camel路由实现上传与下载

import org.apache.camel.builder.RouteBuilder;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class FileRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        // 上传路由:接收Multipart请求,存储到GridFS并返回文件ID
        from("rest:post:/camel/files/upload?consumes=multipart/form-data")
                .setHeader("CamelMongoDbGridFSUploadMetadata", simple("${body.metadata}"))
                .setHeader("CamelMongoDbGridFSFilename", simple("${body.file.fileName}"))
                .to("mongodb-gridfs:myGridFS?operation=upload")
                .transform().simple("${header.CamelMongoDbGridFSFileId}");

        // 下载路由:通过文件ID获取文件并返回
        from("rest:get:/camel/files/download/{fileId}")
                .setHeader("CamelMongoDbGridFSFileId", simple("${header.fileId}"))
                .to("mongodb-gridfs:myGridFS?operation=downloadById")
                .setHeader("Content-Disposition", simple("attachment; filename=\"${header.CamelMongoDbGridFSFilename}\""));
    }
}

事务一致性说明

MongoDB GridFS将文件拆分为fs.chunks(分块数据)与fs.files(元数据)两个集合存储,驱动的GridFS API会保证文件元数据与分块的一致性:上传操作先写入分块,最后原子性写入元数据文档;下载时仅返回完整关联的文件,完全避免了文件系统与数据库分离带来的事务回滚问题,符合你将所有数据统一存储的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 11:40:51