MongoDB文件存储服务
This commit is contained in:
parent
ea9b998c46
commit
b5f03d1c1a
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-modules</artifactId>
|
||||||
|
<version>3.6.4</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.bonus.mongoDB</groupId>
|
||||||
|
<artifactId>bonus-modules-mongodb</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos Config -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Sentinel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot Actuator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- FastDFS -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.tobato</groupId>
|
||||||
|
<artifactId>fastdfs-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Minio -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId>
|
||||||
|
<version>${minio.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Api System -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-api-system</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common Swagger -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-swagger</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.8.12</version> <!-- 版本号可以根据需要调整 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.bonus.mongodb;
|
||||||
|
|
||||||
|
import com.bonus.common.swagger.annotation.EnableCustomSwagger2;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
|
||||||
|
@EnableCustomSwagger2
|
||||||
|
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||||
|
public class BonusMongodbApplication {
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
SpringApplication.run(BonusMongodbApplication.class, args);
|
||||||
|
System.out.println("(♥◠‿◠)ノ゙ MongoDB存储服务模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||||
|
" .-------. ____ __ \n" +
|
||||||
|
" | _ _ \\ \\ \\ / / \n" +
|
||||||
|
" | ( ' ) | \\ _. / ' \n" +
|
||||||
|
" |(_ o _) / _( )_ .' \n" +
|
||||||
|
" | (_,_).' __ ___(_ o _)' \n" +
|
||||||
|
" | |\\ \\ | || |(_,_)' \n" +
|
||||||
|
" | | \\ `' /| `-' / \n" +
|
||||||
|
" | | \\ / \\ / \n" +
|
||||||
|
" ''-' `'-' `-..-' ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.bonus.mongodb.config;
|
||||||
|
|
||||||
|
import com.mongodb.client.MongoClient;
|
||||||
|
import com.mongodb.client.MongoClients;
|
||||||
|
import com.mongodb.client.MongoDatabase;
|
||||||
|
import com.mongodb.client.gridfs.GridFSBucket;
|
||||||
|
import com.mongodb.client.gridfs.GridFSBuckets;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author coisini
|
||||||
|
* @version 1.0
|
||||||
|
* @Description MongoDB配置类
|
||||||
|
* @date Apr 17, 2022
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "spring.data.mongodb")
|
||||||
|
@Data
|
||||||
|
public class MongoConfig {
|
||||||
|
/**
|
||||||
|
* 数据库配置信息
|
||||||
|
*/
|
||||||
|
private String database;
|
||||||
|
private String host;
|
||||||
|
private Integer port;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
// 移除静态修饰符,避免单例模式
|
||||||
|
private MongoClient mongoClient;
|
||||||
|
|
||||||
|
// 使用@Bean注解,并在方法内部进行异常处理
|
||||||
|
@Bean
|
||||||
|
public MongoClient getMongoClient() {
|
||||||
|
if (mongoClient == null) {
|
||||||
|
try {
|
||||||
|
mongoClient = MongoClients.create(String.format("mongodb://%s:%s@%s:%d/%s", URLEncoder.encode(username, "UTF-8"),URLEncoder.encode(password, "UTF-8"), host, port, database));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 在实际应用中应该有更详细的异常处理策略,例如记录日志并抛出自定义异常
|
||||||
|
throw new RuntimeException("Failed to create MongoClient", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mongoClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接返回MongoDatabase实例,依赖注入会处理实例的获取
|
||||||
|
public MongoDatabase getMongoDatabase() {
|
||||||
|
return getMongoClient().getDatabase(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建GridFSBucket的@Bean方法,依赖注入MongoDatabase
|
||||||
|
@Bean
|
||||||
|
public GridFSBucket getGridFsBucket() {
|
||||||
|
return GridFSBuckets.create(getMongoDatabase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.bonus.mongodb.controller;
|
||||||
|
|
||||||
|
import com.bonus.common.core.domain.R;
|
||||||
|
import com.bonus.mongodb.damain.FileExportVo;
|
||||||
|
import com.bonus.mongodb.service.MongodbService;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.poi.ss.formula.functions.T;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mongodb/")
|
||||||
|
@Slf4j
|
||||||
|
public class MongodbController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MongodbService mongodbService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "单文件上传")
|
||||||
|
@PostMapping("uploadFile")
|
||||||
|
public R<FileExportVo> uploadFile(MultipartFile file) {
|
||||||
|
try {
|
||||||
|
FileExportVo fileExportVo = mongodbService.uploadFile(file);
|
||||||
|
return R.ok(fileExportVo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("单文件上传", e);
|
||||||
|
return R.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "多文件上传")
|
||||||
|
@PostMapping("uploadFiles")
|
||||||
|
public R<List<FileExportVo>> uploadFiles(MultipartFile[] files) {
|
||||||
|
try {
|
||||||
|
List<MultipartFile> multipartFiles = Arrays.asList(files);
|
||||||
|
List<FileExportVo> list = mongodbService.uploadFiles(multipartFiles);
|
||||||
|
return R.ok(list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("多文件上传", e);
|
||||||
|
return R.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "文件删除")
|
||||||
|
@PostMapping("delFile")
|
||||||
|
public R<T> delFile(String fileId) {
|
||||||
|
try {
|
||||||
|
mongodbService.removeFile(fileId);
|
||||||
|
return R.ok();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文件删除", e);
|
||||||
|
return R.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取文件base64")
|
||||||
|
@PostMapping("getFileBase64")
|
||||||
|
public R<byte[]> getFileBase64(String fileId) {
|
||||||
|
try {
|
||||||
|
FileExportVo fileExportVo = mongodbService.downloadFile(fileId);
|
||||||
|
return R.ok(fileExportVo.getData());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取文件base64", e);
|
||||||
|
return R.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.bonus.mongodb.damain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileExportVo implements Serializable {
|
||||||
|
|
||||||
|
private String file;
|
||||||
|
|
||||||
|
private String fileId;
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
private String suffix;
|
||||||
|
|
||||||
|
private long fileSize;
|
||||||
|
|
||||||
|
private String sourceId;
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String fileType;
|
||||||
|
/**
|
||||||
|
* 资源类型
|
||||||
|
*/
|
||||||
|
private String sourceType;
|
||||||
|
|
||||||
|
private String updaetTime;
|
||||||
|
|
||||||
|
private byte[] data;
|
||||||
|
|
||||||
|
public FileExportVo(MongoFile mongoFile) {
|
||||||
|
BeanUtil.copyProperties(mongoFile, this);
|
||||||
|
if (Objects.nonNull(mongoFile.getContent())) {
|
||||||
|
this.data = mongoFile.getContent().getData();
|
||||||
|
}
|
||||||
|
this.fileId = mongoFile.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.bonus.mongodb.damain;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.bson.types.Binary;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
@Builder
|
||||||
|
@Data
|
||||||
|
@Document(collection = "files")
|
||||||
|
public class MongoFile {
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@Id
|
||||||
|
public String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名称
|
||||||
|
*/
|
||||||
|
public String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件大小
|
||||||
|
*/
|
||||||
|
public long fileSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传时间
|
||||||
|
*/
|
||||||
|
public String uploadDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5值
|
||||||
|
*/
|
||||||
|
public String md5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件内容
|
||||||
|
*/
|
||||||
|
private Binary content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件类型
|
||||||
|
*/
|
||||||
|
public String contentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件后缀名
|
||||||
|
*/
|
||||||
|
public String suffix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件描述
|
||||||
|
*/
|
||||||
|
public String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 大文件管理GridFS的ID
|
||||||
|
*/
|
||||||
|
private String gridFsId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.bonus.mongodb.repository;
|
||||||
|
|
||||||
|
import com.bonus.mongodb.damain.MongoFile;
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||||
|
|
||||||
|
public interface MongoFileRepository extends MongoRepository<MongoFile, String> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.bonus.mongodb.service;
|
||||||
|
|
||||||
|
import com.bonus.mongodb.damain.FileExportVo;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface MongodbService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return FileExportVo
|
||||||
|
* @throws Exception
|
||||||
|
* @description
|
||||||
|
* @date 2024/3/11 15:44
|
||||||
|
*/
|
||||||
|
FileExportVo uploadFile(MultipartFile file) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多文件上传
|
||||||
|
*
|
||||||
|
* @param files
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<FileExportVo> uploadFiles(List<MultipartFile> files);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
FileExportVo downloadFile(String fileId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件删除
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
*/
|
||||||
|
void removeFile(String fileId);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,279 @@
|
||||||
|
package com.bonus.mongodb.service.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.bonus.common.core.utils.DateUtils;
|
||||||
|
import com.bonus.mongodb.damain.FileExportVo;
|
||||||
|
import com.bonus.mongodb.damain.MongoFile;
|
||||||
|
import com.bonus.mongodb.repository.MongoFileRepository;
|
||||||
|
import com.bonus.mongodb.service.MongodbService;
|
||||||
|
import com.bonus.mongodb.utils.Md5Util;
|
||||||
|
import com.mongodb.client.gridfs.GridFSBucket;
|
||||||
|
import com.mongodb.client.gridfs.GridFSDownloadStream;
|
||||||
|
import com.mongodb.client.gridfs.model.GridFSFile;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.bson.types.Binary;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
|
import org.springframework.data.mongodb.gridfs.GridFsResource;
|
||||||
|
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class MongodbServiceImpl implements MongodbService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MongodbServiceImpl.class);
|
||||||
|
private final MongoFileRepository mongoFileRepository;
|
||||||
|
private final MongoTemplate mongoTemplate;
|
||||||
|
private final GridFsTemplate gridFsTemplate;
|
||||||
|
private final GridFSBucket gridFSBucket;
|
||||||
|
|
||||||
|
private static final int MAX_SIZE = 16777216;
|
||||||
|
private static final String SUFFIX = ".";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多文件上传
|
||||||
|
*
|
||||||
|
* @param files
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<FileExportVo> uploadFiles(List<MultipartFile> files) {
|
||||||
|
|
||||||
|
return files.stream().map(file -> {
|
||||||
|
try {
|
||||||
|
return this.uploadFile(file);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public FileExportVo uploadFile(MultipartFile file) throws Exception {
|
||||||
|
if (file.getSize() > MAX_SIZE) {
|
||||||
|
return this.saveGridFsFile(file);
|
||||||
|
} else {
|
||||||
|
return this.saveBinaryFile(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public FileExportVo downloadFile(String fileId) {
|
||||||
|
Optional<MongoFile> option = this.getBinaryFileById(fileId);
|
||||||
|
|
||||||
|
if (option.isPresent()) {
|
||||||
|
MongoFile mongoFile = option.get();
|
||||||
|
if (Objects.isNull(mongoFile.getContent())) {
|
||||||
|
option = this.getGridFsFileById(fileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return option.map(FileExportVo::new).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件删除
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removeFile(String fileId) {
|
||||||
|
Optional<MongoFile> option = this.getBinaryFileById(fileId);
|
||||||
|
|
||||||
|
if (option.isPresent()) {
|
||||||
|
if (Objects.nonNull(option.get().getGridFsId())) {
|
||||||
|
this.removeGridFsFile(fileId);
|
||||||
|
} else {
|
||||||
|
this.removeBinaryFile(fileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Binary文件
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
*/
|
||||||
|
public void removeBinaryFile(String fileId) {
|
||||||
|
mongoFileRepository.deleteById(fileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除GridFs文件
|
||||||
|
*
|
||||||
|
* @param fileId
|
||||||
|
*/
|
||||||
|
public void removeGridFsFile(String fileId) {
|
||||||
|
// TODO 根据id查询文件
|
||||||
|
MongoFile mongoFile = mongoTemplate.findById(fileId, MongoFile.class);
|
||||||
|
if (Objects.nonNull(mongoFile)) {
|
||||||
|
// TODO 根据文件ID删除fs.files和fs.chunks中的记录
|
||||||
|
Query deleteFileQuery = new Query().addCriteria(Criteria.where("filename").is(mongoFile.getGridFsId()));
|
||||||
|
gridFsTemplate.delete(deleteFileQuery);
|
||||||
|
// TODO 删除集合mongoFile中的数据
|
||||||
|
Query deleteQuery = new Query(Criteria.where("id").is(fileId));
|
||||||
|
mongoTemplate.remove(deleteQuery, MongoFile.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存Binary文件(小文件)
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public FileExportVo saveBinaryFile(MultipartFile file) throws Exception {
|
||||||
|
|
||||||
|
String suffix = getFileSuffix(file);
|
||||||
|
MongoFile mongoFile = mongoFileRepository.save(
|
||||||
|
MongoFile.builder()
|
||||||
|
.fileName(file.getOriginalFilename())
|
||||||
|
.fileSize(file.getSize())
|
||||||
|
.content(new Binary(file.getBytes()))
|
||||||
|
.contentType(file.getContentType())
|
||||||
|
.uploadDate(DateUtils.getTime())
|
||||||
|
.suffix(suffix)
|
||||||
|
.md5(Md5Util.getMd5(file.getInputStream()))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
return new FileExportVo(mongoFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存GridFs文件(大文件)
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public FileExportVo saveGridFsFile(MultipartFile file) throws Exception {
|
||||||
|
String suffix = getFileSuffix(file);
|
||||||
|
|
||||||
|
String gridFsId = this.storeFileToGridFs(file.getInputStream(), file.getContentType());
|
||||||
|
|
||||||
|
MongoFile mongoFile = mongoTemplate.save(
|
||||||
|
MongoFile.builder()
|
||||||
|
.fileName(file.getOriginalFilename())
|
||||||
|
.fileSize(file.getSize())
|
||||||
|
.contentType(file.getContentType())
|
||||||
|
.uploadDate(DateUtils.getTime())
|
||||||
|
.suffix(suffix)
|
||||||
|
.md5(Md5Util.getMd5(file.getInputStream()))
|
||||||
|
.gridFsId(gridFsId)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
return new FileExportVo(mongoFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件到Mongodb的GridFs中
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* @param contentType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String storeFileToGridFs(InputStream in, String contentType) throws IOException {
|
||||||
|
try {
|
||||||
|
String gridFsId = IdUtil.simpleUUID();
|
||||||
|
// TODO 将文件存储进GridFS中
|
||||||
|
gridFsTemplate.store(in, gridFsId, contentType);
|
||||||
|
return gridFsId;
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("上传文件到Mongodb的GridFs中失败",e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Binary文件
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Optional<MongoFile> getBinaryFileById(String id) {
|
||||||
|
return mongoFileRepository.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Grid文件
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Optional<MongoFile> getGridFsFileById(String id) {
|
||||||
|
MongoFile mongoFile = mongoTemplate.findById(id, MongoFile.class);
|
||||||
|
if (Objects.nonNull(mongoFile)) {
|
||||||
|
Query gridQuery = new Query().addCriteria(Criteria.where("filename").is(mongoFile.getGridFsId()));
|
||||||
|
try {
|
||||||
|
// TODO 根据id查询文件
|
||||||
|
GridFSFile fsFile = gridFsTemplate.findOne(gridQuery);
|
||||||
|
// TODO 打开流下载对象
|
||||||
|
GridFSDownloadStream in = gridFSBucket.openDownloadStream(fsFile.getObjectId());
|
||||||
|
if (in.getGridFSFile().getLength() > 0) {
|
||||||
|
// TODO 获取流对象
|
||||||
|
GridFsResource resource = new GridFsResource(fsFile, in);
|
||||||
|
// TODO 获取数据
|
||||||
|
mongoFile.setContent(new Binary(IoUtil.readBytes(resource.getInputStream())));
|
||||||
|
return Optional.of(mongoFile);
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件后缀
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getFileSuffix(MultipartFile file) {
|
||||||
|
String suffix = "";
|
||||||
|
if (Objects.requireNonNull(file.getOriginalFilename()).contains(SUFFIX)) {
|
||||||
|
suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||||
|
}
|
||||||
|
return suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.bonus.mongodb.utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 10488
|
||||||
|
* @version 1.0
|
||||||
|
* @Description MD5工具类
|
||||||
|
* @date Apr 8, 2022
|
||||||
|
*/
|
||||||
|
public class Md5Util {
|
||||||
|
/**
|
||||||
|
* 获取该输入流的MD5值
|
||||||
|
*/
|
||||||
|
public static String getMd5(InputStream is) throws NoSuchAlgorithmException, IOException {
|
||||||
|
StringBuffer md5 = new StringBuffer();
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] dataBytes = new byte[1024];
|
||||||
|
|
||||||
|
int nread = 0;
|
||||||
|
while ((nread = is.read(dataBytes)) != -1) {
|
||||||
|
md.update(dataBytes, 0, nread);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
byte[] mdbytes = md.digest();
|
||||||
|
|
||||||
|
// convert the byte to hex format
|
||||||
|
for (int i = 0; i < mdbytes.length; i++) {
|
||||||
|
md5.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
return md5.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
Spring Boot Version: ${spring-boot.version}
|
||||||
|
Spring Application Name: ${spring.application.name}
|
||||||
|
_ _
|
||||||
|
| | | |
|
||||||
|
| |__ ___ _ __ _ _ ___ ______ ___ | |__ ___
|
||||||
|
| '_ \ / _ \ | '_ \ | | | | / __| |______| / _ \ | '_ \ / __|
|
||||||
|
| |_) | | (_) | | | | | | |_| | \__ \ | (_) | | |_) | \__ \
|
||||||
|
|_.__/ \___/ |_| |_| \__,_| |___/ \___/ |_.__/ |___/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 9206
|
||||||
|
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: bonus-mongodb
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 192.168.0.14:8848
|
||||||
|
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 192.168.0.14:8848
|
||||||
|
namespace: f1fcd3ea-9460-4597-8acd-0f334527017c
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
<!-- 日志存放路径 -->
|
||||||
|
<property name="log.path" value="logs/bonus-file" />
|
||||||
|
<!-- 日志输出格式 -->
|
||||||
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/info.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/error.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>ERROR</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统模块日志级别控制 -->
|
||||||
|
<logger name="com.bonus" level="info" />
|
||||||
|
<!-- Spring日志级别控制 -->
|
||||||
|
<logger name="org.springframework" level="warn" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统操作日志-->
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="file_info" />
|
||||||
|
<appender-ref ref="file_error" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
Loading…
Reference in New Issue