SpringBoot MongoDB GridFsTemplate实现文件管理

1. 添加maven

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

2. 配置文件GridFsTemplate实现临时文件和正式文件存储桶分离

@Configuration
public class GridFsConfig {

    @Bean(name = "gridTempFsTemplate")
    public GridFsTemplate gridTempFsTemplate(MongoDatabaseFactory dbFactory, MongoConverter converter) {
        return new GridFsTemplate(dbFactory, converter, "tempFs");
    }

    @Bean(name = "gridFormalFsTemplate")
    public GridFsTemplate gridFormalFsTemplate(MongoDatabaseFactory dbFactory, MongoConverter converter) {
        return new GridFsTemplate(dbFactory, converter, "formalFs");
    }
}

3. 创建GridFsTemplateUtil工具类管理文件的上传、下载和删除

@Slf4j
@Component
public class GridFsTemplateUtil {

    @Resource(name = "gridTempFsTemplate")
    private GridFsTemplate gridTempFsTemplate;

    @Resource(name = "gridFormalFsTemplate")
    private GridFsTemplate gridFormalFsTemplate;


    /**
     * 上传临时文件
     *
     * @param file 文件
     * @return {@link String}
     */
    public String saveTempFile(MultipartFile file, String fileName) {
        DBObject metaData = new BasicDBObject();
        metaData.put("createTime", new Date());
        metaData.put("createUser", SecurityContextUtils.getUserId());
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
            //文件流:inputStream
            //id:文件的唯一标识id
            //file.getContentType():内容类型
            //metaData:元数据
            return gridTempFsTemplate.store(inputStream, fileName, file.getContentType(), metaData).toString();
        } catch (IOException e) {
            log.error("上传失败", e);
            throw new MyException(ErrorCode.ERROR);
        }
    }

    /**
     * 上传临时文件
     *
     * @param file 文件
     * @return {@link String}
     */
    public String saveTempFile(MultipartFile file) {
        DBObject metaData = new BasicDBObject();
        metaData.put("createTime", new Date());
        metaData.put("createUser", SecurityContextUtils.getUserId());
        String fileName = file.getOriginalFilename();
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
            //文件流:inputStream
            //id:文件的唯一标识id
            //file.getContentType():内容类型
            //metaData:元数据
            return gridTempFsTemplate.store(inputStream, fileName, file.getContentType(), metaData).toString();
        } catch (IOException e) {
            log.error("上传失败", e);
            throw new MyException(ErrorCode.ERROR);
        }
    }

    /**
     * 上传正式文件
     *
     * @param file 文件
     * @return {@link String}
     */
    public String saveFormalFsFile(MultipartFile file) {
        DBObject metaData = new BasicDBObject();
        metaData.put("createTime", new Date());
        metaData.put("createUser", SecurityContextUtils.getUserId());
        String fileName = file.getOriginalFilename();
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
            //文件流:inputStream
            //id:文件的唯一标识id
            //file.getContentType():内容类型
            //metaData:元数据
            return gridFormalFsTemplate.store(inputStream, fileName, file.getContentType(), metaData).toString();
        } catch (IOException e) {
            log.error("上传失败", e);
            throw new MyException(ErrorCode.ERROR);
        }
    }

    /**
     * 上传正式文件
     *
     * @param file 文件
     * @return {@link String}
     */
    public String saveFormalFsFile(MultipartFile file, String fileName) {
        DBObject metaData = new BasicDBObject();
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
            //文件流:inputStream
            //id:文件的唯一标识id
            //file.getContentType():内容类型
            //metaData:元数据
            return gridFormalFsTemplate.store(inputStream, fileName, file.getContentType(), metaData).toString();
        } catch (IOException e) {
            log.error("上传失败", e);
            throw new MyException(ErrorCode.ERROR);
        }
        }

            /**
            * 获取临时文件
            *
            * @param id 文件id
            * @return {@link GridFsResource}
            */
            public GridFsResource getTempFile(String id) {
            log.info("Getting file.." + id);
            GridFSFile gridFsFile = gridTempFsTemplate
            .findOne(new Query(Criteria.where("_id").is(id)));
            if (gridFsFile != null) {
            return gridTempFsTemplate.getResource(gridFsFile);
        }
            throw new MyException(ErrorCode.ERROR);
        }

            /**
            * 获取正式文件
            *
            * @param id 文件id
            * @return {@link GridFsResource}
            */
            public GridFsResource getFormalFile(String id) {
            log.info("Getting file.." + id);
            GridFSFile gridFsFile = gridTempFsTemplate
            .findOne(new Query(Criteria.where("_id").is(id)));
            if (gridFsFile != null) {
            return gridFormalFsTemplate.getResource(gridFsFile);
        }
            throw new MyException(ErrorCode.ERROR);
        }

            /**
            * 删除临时文件
            *
            * @param id 文件id
            */
            public void deleteTempFile(String id) {
            gridTempFsTemplate.delete(new Query().addCriteria(Criteria.where("_id").is(id)));
        }

            /**
            * 删除正式文件
            *
            * @param id 文件id
            */
            public void deleteFormalFile(String id) {
            gridFormalFsTemplate.delete(new Query().addCriteria(Criteria.where("_id").is(id)));
        }
        }

4. 创建GridFsTemplateFileController控制器暴露上传、下载和删除接口

@Slf4j
@RestController
@RequestMapping("/gridFsFile")
@Api(tags = "上传文件控制器")
public class GridFsTemplateFileController  {

    @Autowired
    private GridFsTemplateUtil gridFsTemplateUtil;

    /**
     * 上传临时文件
     *
     * @param file 文件
     * @return {@link RespJson}
     */
    @ApiOperation(value = "上传临时文件(mongodb)", notes = "上传临时文件(mongodb)")
    @PostMapping(value = "uploadTempFile", headers = "content-type=multipart/form-data")
    public RespJson<String> uploadTempFile(@RequestPart(value = "file") MultipartFile file) {
        return RespJson.success(gridFsTemplateUtil.saveTempFile(file));
    }

    /**
     * 上传正式文件
     *
     * @param file 文件
     * @return {@link RespJson}
     */
    @ApiOperation(value = "上传正式文件(mongodb)", notes = "上传正式文件(mongodb)")
    @PostMapping(value = "uploadFormalFile", headers = "content-type=multipart/form-data")
    public RespJson<String> uploadFormalFile(@RequestPart(value = "file") MultipartFile file) {
        return RespJson.success(gridFsTemplateUtil.saveFormalFsFile(file));
    }

    /**
     * 获取临时文件
     *
     * @param id 文件id
     * @return {@link RespJson}
     */
    @ApiOperation(value = "获取临时文件(mongodb)", notes = "获取临时文件(mongodb)")
    @GetMapping(value = "getTempFile")
    public ResponseEntity<InputStreamResource> getTempFile(HttpServletRequest request,
                                            HttpServletResponse response,
                                            @RequestParam String id) {
       try {
           GridFsResource tempFile = gridFsTemplateUtil.getTempFile(id);
           InputStream inputStream = tempFile.getInputStream();
           // 设置HTTP响应头
           HttpHeaders headers = new HttpHeaders();
           headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + tempFile.getFilename());
           headers.add(HttpHeaders.CONTENT_TYPE, tempFile.getContentType());
           headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(Objects.requireNonNull(tempFile.getGridFSFile()).getLength()));
           // 返回文件流
           return ResponseEntity.ok()
                   .headers(headers)
                   .contentType(MediaType.parseMediaType(tempFile.getContentType()))
                   .body(new InputStreamResource(inputStream));
       }catch (Exception e){
           throw new MyException(ErrorCode.ERROR);
       }
    }

    /**
     * 获取正式文件
     *
     * @param id 文件id
     * @return {@link RespJson}
     */
    @ApiOperation(value = "获取正式文件(mongodb)", notes = "获取正式文件(mongodb)")
    @GetMapping(value = "getFormalFile")
    public ResponseEntity<InputStreamResource> getFormalFile(HttpServletRequest request,
                                                             HttpServletResponse response,
                                                             @RequestParam String id) {
        try {
            GridFsResource tempFile = gridFsTemplateUtil.getFormalFile(id);
            InputStream inputStream = tempFile.getInputStream();
            // 设置HTTP响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + tempFile.getFilename());
            headers.add(HttpHeaders.CONTENT_TYPE, tempFile.getContentType());
            headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(Objects.requireNonNull(tempFile.getGridFSFile()).getLength()));
            // 返回文件流
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.parseMediaType(tempFile.getContentType()))
                    .body(new InputStreamResource(inputStream));
        }catch (Exception e){
            throw new MyException(ErrorCode.ERROR);
        }
    }

    /**
     * 删除临时文件
     *
     * @param id 文件id
     * @return {@link RespJson}
     */
    @ApiOperation(value = "删除临时文件(mongodb)", notes = "删除临时文件(mongodb)")
    @GetMapping(value = "deleteTempFile")
    public RespJson<Boolean> deleteTempFile(@RequestParam String id) {
        gridFsTemplateUtil.deleteTempFile(id);
        return RespJson.success();
    }

    /**
     * 获取正式文件
     *
     * @param id 文件id
     * @return {@link RespJson}
     */
    @ApiOperation(value = "获取正式文件(mongodb)", notes = "获取正式文件(mongodb)")
    @GetMapping(value = "deleteFormalFile")
    public RespJson<Boolean> deleteFormalFile(@RequestParam String id) {
        gridFsTemplateUtil.deleteFormalFile(id);
        return RespJson.success();
    }
}

5.总结

总体来说,GridFsTemplate提供了方便的API和高度可扩展的存储方案,使得在MongoDB中存储和检索大型文件变得更加容易和高效。

相关推荐
Asthenia04123 小时前
浏览器缓存机制深度解析:电商场景下的性能优化实践
后端
databook4 小时前
『Python底层原理』--Python对象系统探秘
后端·python
超爱吃士力架5 小时前
MySQL 中的回表是什么?
java·后端·面试
追逐时光者6 小时前
Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
后端·.net
典龙3306 小时前
如何使用springboot项目如何实现小程序里面商品的浏览记录功能案例
spring boot
苏三说技术6 小时前
10亿数据,如何迁移?
后端
bobz9656 小时前
openvpn 显示已经建立,但是 ping 不通
后端
customer087 小时前
【开源免费】基于SpringBoot+Vue.JS个人博客系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
qq_459238497 小时前
SpringBoot整合Redis和Redision锁
spring boot·redis·后端
灰色人生qwer7 小时前
SpringBoot 项目配置日志输出
java·spring boot·后端