最近项目要用到文件上传下载功能,但是这些音频文件都很大,放到关系型数据库就不太好了(其实是太不好了),占内存不说还慢的要死,所以考虑使用分布式文件系统或者非关系型数据库来实现。由于分布式文件系统没有用过,怕出问题不好解决,所以最后决定使用mongodb来实现,正好框架使用的是springboot2.x,看到官方也集成了mongodb,这就再好不过了。
项目地址:https://github.com/hanxiaochuang666/mongodbDemo
最后的效果就是普通的文件上传下载的效果。ps:postman可以测试文件上传和下载,并且还能播放音频文件,厉害!!!
请求连接:
http://localhost:9991/mongo/downLoadFile?id=5cfe278f71797006c862119e
返回一个音频文件,可以播放:
我用到了文件工具包所以导入了commons-io,如果不用这个也可以,手写response就行了
org.springframework.boot
spring-boot-starter-data-mongodb
commons-io
commons-io
2.4
在配置文件增加如下配置:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
data:
mongodb:
uri: mongodb://127.0.0.1:27017/hanchuang
servlet:
multipart:
#是否支持批量上传
enabled: true
#上传文件最大为 100M
max-file-size: 100MB
#上传总数据大小 200M
max-request-size: 200MB
使用的是springboot提供的模板类:GridFsTemplate
import com.hc.bootdemo.config.GridConfig;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;
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.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @desc
* @Author:hanchuang
* @Version 1.0
* @Date:add on 16:11 2019/6/10
*/
@RestController
@RequestMapping(value = "/mongo")
public class mongoTest {
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private GridConfig gridConfig;
// 音频文件上传
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public ObjectId uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
return gridFsTemplate.store(file.getInputStream(), file.getOriginalFilename(), file.getContentType());
}
// 音频文件下载
@RequestMapping(value = "/getFile", method = RequestMethod.GET)
public void getFile(@RequestParam(value = "id") String id,HttpServletResponse response) throws IOException {
System.out.println("id================"+id);
GridFSFile gridFSFile = gridFsTemplate.findOne(new Query().addCriteria(Criteria.where("_id").is(id)));
GridFsResource fsResource = gridConfig.convertGridFSFile2Resource(gridFSFile);
IOUtils.copy(fsResource.getInputStream(),response.getOutputStream());
}
@RequestMapping(value = "/deleteFile", method = RequestMethod.DELETE)
public int deleteFile(@RequestParam(value = "fileName") String fileName) {
gridFsTemplate.delete(new Query().addCriteria(Criteria.where("filename").is(fileName)));
return 0;
}
}
注意:springboot2.x时代,文件下载的时候使用的gridFsTemplate.findOne(query)返回类型由GridFSDBFile改为GridFSFile,所以下面这种方式不能用了
GridFSDBFile gridFSDBFile = gridFsTemplate.findOne(new Query().addCriteria(Criteria.where("_id").is(id)));
gridFSDBFile.writeTo(response.getOutputStream());
解决方案:把GridFSFile 转成 GridFsResource
做成一个bean配置
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
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;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @desc
* @Author:hanchuang
* @Version 1.0
* @Date:add on 17:20 2019/6/10
*/
@Configuration
@Component
public class GridConfig {
@Autowired
private MongoDbFactory mongoDbFactory;
@Autowired
private GridFSBucket gridFSBucket;
// 将GridFSFile 转成 GridFsResource
public GridFsResource convertGridFSFile2Resource(GridFSFile gridFsFile) {
GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFsFile.getObjectId());
return new GridFsResource(gridFsFile, gridFSDownloadStream);
}
@Bean
public GridFSBucket getGridFSBuckets() {
MongoDatabase db = mongoDbFactory.getDb();
return GridFSBuckets.create(db);
}
}
url:http://localhost:9991/mongo/uploadFile 参数就是一个文件
选择一个MP3文件然后上传:
使用compass查看一下mongodb库里的数据,如果没有compass可以使用shell操作查看,也可以看这个文章:windows安装MongDB4.0之正确的安装姿势,最后面推荐了两个可视化工具
url:http://localhost:9991/mongo/downLoadFile?id=5cff5293717970223c8db82c id是上传时候mongodb给返回的文件id,是自动生成的:
完。