一个项目(本文是基于SpringBoot2.0.5项目环境下的操作)里面需要用到MongoDB 上传文件的操作,记录 一下开发的过程。另附一个使用swagger进行调试使用的小坑。
1.引入项目依赖(pom.xml)
<!-- mogodb 的支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2.在application.yml配置文件中添加如下配置(这里dev为账号,123456为你的密码,作用的数据库为just,你需要提前设置一个账号并且创建一个数据库,让用户具有owner的权限)
spring:
# mongodb的配置
data:
mongodb:
uri: mongodb://dev:123456@localhost:27017/just
3.编写配置类MongoConf.java
package com.justcs.config;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
/**
* mongodb的配置类
* 解决新版本不支持获取GGridFSDBFile
*/
@Configuration
public class MongoConf {
@Autowired
private MongoDbFactory mongoDbFactory;
@Autowired
private GridFSBucket gridFSBucket;
@Bean
public GridFSBucket getGridFSBucket() {
MongoDatabase db = mongoDbFactory.getDb();
return GridFSBuckets.create(db);
}
}
4.编写Controller测试类:
package com.justcs.controller;
import com.justcs.utils.JSONResult;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
/**
* 文件上传下载控制类
*/
@Api(value = "文件上传下载控制类")
@Controller
@RequestMapping("/file")
public class MongoDBGFSController {
private static final Logger logger = LoggerFactory.getLogger(MongoDBGFSController.class);
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private GridFSBucket gridFSBucket;
/**
* 上传文件
*
* @param file
* @return
* @throws IOException
* @throws ServletException
*/
@ApiOperation(value = "上传文件测试", notes = "上传文件测试demo")
@PostMapping("upload")
@ResponseBody
public JSONResult uploadFile(@RequestParam("file") MultipartFile file) throws IOException, ServletException {
// 获得提交的文件名
String fileName = file.getOriginalFilename();
// 获取文件输入流
InputStream ins = file.getInputStream();
// 获取文件类型
String contentType = file.getContentType();
// 将文件存储到mongodb中
ObjectId objectId = gridFsTemplate.store(ins, fileName, contentType);
logger.info("保存成功,objectId:" + objectId);
return JSONResult.ok(objectId);
}
/**
* 下载文件
*
* @param fileId
* @param request
* @param response
* @throws IOException
*/
@ApiOperation(value = "下载文件测试", notes = "下载文件测试demo")
@RequestMapping(value = "/download", method = {RequestMethod.GET, RequestMethod.POST})
public void downloadFile(@RequestParam(name = "file_id") String fileId,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
logger.info("准备下载文件....");
Query query = Query.query(Criteria.where("_id").is(fileId));
// 查询单个文件
GridFSFile gridFSFile = gridFsTemplate.findOne(query);
if (gridFSFile == null) {
return;
}
String fileName = gridFSFile.getFilename().replace(",", "");
String contentType = gridFSFile.getMetadata().get("_contentType").toString();
// 通知浏览器进行文件下载
response.setContentType(contentType);
response.setHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
GridFsResource resource = new GridFsResource(gridFSFile, gridFSDownloadStream);
OutputStream outputStream = response.getOutputStream();
InputStream inputStream = resource.getInputStream();
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
outputStream.close();
inputStream.close();
}
}
5.让项目跑起来,这里我用的是swagger来进行调试的(使用前后端分离的方式来开发)
测试上传文件:
成功上传(这里我使用的mongodb的可视化工具Studio 3T):
测试下载文件:(敲黑板了!重点问题来了,一定不要点swagger返回的文件下载链接,而是要自己重新复制一个连接在浏览器访问才能正确下载文件,否则你得到的文件是有问题的,或者根本打不开!)
而是在浏览器中访问: