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中存储和检索大型文件变得更加容易和高效。