基于mongodb-gridfs数据库实现文件服务,二进制文件的上传、下载
开发语言:java-jdk1.8,springboot2.2.5
mongodb4.0
创建项目fileserver
pom.xml
<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>
<groupId>com.siniswift</groupId>
<artifactId>fileserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>fileserver</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!-- <gson.version>2.2.4</gson.version> -->
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId> org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version> 1.1.0 </version>
<scope>test</scope>
</dependency>
<!-- springboot 版druid -->
<!-- <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency> -->
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mongodb 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- comons lang -->
<!-- <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>$NO-MVN-MAN-VER$
</dependency> -->
<!-- http post -->
<!-- <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>$NO-MVN-MAN-VER$
</dependency> -->
<!-- fastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
<!--gson-->
<!-- <dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency> -->
</dependencies>
<build>
<finalName>fileserver</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.siniswift.fileserver.Application</mainClass>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.properties
#服务端口号
server.port=9000
server.context-path=/fileserver
#集群
spring.data.mongodb.uri=mongodb://192.168.125.95:27017,192.168.121.61:27020/mxx?replicaSet=rs1&slaveOk=true&readPreference=secondary
##文件临时存放路径
file.dir=D:/fileserver/file
FileController.java
/**
* 文件上传
* @param request
* @param response
* bistype:release
* name:filename.zip
* md5:file-md5
* size:fileSize
*/
@RequestMapping(value = "/uploadAll")
public void uploadAll(HttpServletRequest request,HttpServletResponse response){
log.info("文件上传:uploadAll");
Map dto = new HashMap<String,String>();
try{
//String fileGuid = request.getParameter("guid");//上传前从文件服务器获取的唯一码,或存储后的返回值
String bistype = request.getParameter("bistype");//manual/performance/naipchart/chart/announcement
String name = request.getParameter("name").trim();
String fileType = name.substring(name.lastIndexOf(".")+1);
String md5 = request.getParameter("md5");//上传完成后的检查使用-预留参数
long fileSize = Long.valueOf(request.getParameter("size"));
MultipartHttpServletRequest multipartRequest =(MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile("data");
DBObject metaData = new BasicDBObject();
metaData.put("bsType", bistype);
metaData.put("fileSize", fileSize);
String obejctId = writerServer.writer(file.getInputStream(), name, metaData);
dto.put("Success", "Yes");
dto.put("fileId", obejctId);
}catch(Exception e){
e.printStackTrace();
log.error("文件上传失败");
dto.put("Success", "No");
log.info("程序异常");
}
String jsonString = JSON.toJSONString(dto);
try {
response.getWriter().write(jsonString);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 文件信息查询
* @param request
* @param response
* fileid:fileid
*/
@RequestMapping(value = "/fileInfoById")
public void fileInfoById(HttpServletRequest request,HttpServletResponse response){
log.info("文件查询:fileInfoById");
Map dto = new HashMap<String,String>();
try{
String fileid = request.getParameter("fileId");
//String fileName = request.getParameter("fileName").trim();
String fileInfo = readService.gridFSFileById(fileid);
dto.put("Success", "Yes");
dto.put("fileInfo", fileInfo);
}catch(Exception e){
e.printStackTrace();
log.error("文件上传失败");
dto.put("Success", "No");
log.info("程序异常");
}
String jsonString = JSON.toJSONString(dto);
try {
response.getWriter().write(jsonString);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 通过文件fileId下载文件
*
* @param fileId 文件fileId
* @param response 文件输出流
*/
@RequestMapping(value = "/downloadByFileId")
public void downloadByFileId(@RequestParam(value = "fileId") ObjectId fileId, HttpServletResponse response) {
String fileName = null;
try {
fileName = readService.downloadByFileId(fileId,response.getOutputStream());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setHeader("Content-Disposition", "inline;filename=\"" + fileName + "\"");
response.setContentType("application/octet-stream");
}
WriterService.java
/**
* 文件二进制流存储入库
* @param inputStream
* @param fileName
* @param metaData
* @return
*/
public String writer(InputStream inputStream,String fileName,DBObject metaData) {
long t1 = System.currentTimeMillis();
//System.out.println("读取文件流:大小="+f.length()+"耗时:"+(t1-t0));
ObjectId id = gridFsTemplate.store(inputStream, fileName, metaData);
long t2 = System.currentTimeMillis();
System.out.println("文件写入:"+(t2-t1));
return id.toString();
}
/**
* 删除文件
* @throws Exception
*/
public void deleteById(String fileid) throws Exception {
log.info("删除文件:id="+fileid);
gridFsTemplate.delete(new Query().addCriteria(Criteria.where("_id").is(fileid)));
}
ReadService.java
/**
* 文件流读取,
* @param fileId
* @return 文件流 os
* @throws FileNotFoundException
*/
public void downloadByFileId(ObjectId fileId,OutputStream os) throws FileNotFoundException {
log.info("开始下载文件流:"+fileId);
long t0 = System.currentTimeMillis();
GridFSFile gridFsFile = gridFsTemplate.findOne(new Query().addCriteria(Criteria.where("_id").is(fileId)));
if (gridFsFile != null) {
GridFsResource gridFsResource = gridFsTemplate.getResource(gridFsFile);
InputStream is;
try {
is = gridFsResource.getInputStream();
FileUtil.copyStream(is, os, false);
} catch (IllegalStateException | IOException e) {
log.error("下载文件流程序异常");
e.printStackTrace();
}
}
long t1 = System.currentTimeMillis();
log.info("读文件结束:"+(t1-t0));
}
分段上传-待补充
分段读取-待补充