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