MongoDB GridFS是MongoDB大文件存储的机制,存储和检索超过BSON文档大小限制为16MB的文件的规范。
1、首先创建一个maven项目,spring-boot-mongodb-demo
这里使用的是Spring Tool Suite 4
2、在pom.xml文件中,引入MongoDB依赖实现集成。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodbartifactId>
dependency>
由于这是Web项目所以还需要引入以下依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
3、在application.properties文件中,配置MongoDB的连接信息
spring.data.mongodb.database=spring-boot-mongodb
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
其中:
·spring.data.mongodb.database:配置的是MongoDB中数据库名称
·spring.data.mongodb.host:配置的是MongoDB的服务地址。
·spring.data.mongodb.port:配置的是MongoDB数据库端口,默认是27017.
4、创建一个上传文件到MongoDB GridFS的GridController类
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
@RestController
public class GridController {
@Autowired
private GridFsTemplate gridFsTemplate;
@GetMapping("/upload")
public String uploadFile() throws Exception {
File file = new File("e:/input.txt");
InputStream content = new FileInputStream(file);
DBObject metadata = new BasicDBObject("userId","1");
ObjectId fileId = gridFsTemplate.store(content, file.getName(),"file/files",metadata);
System.out.println(fileId.toString());
return "success";
}
}
代码解析:
GridFsTemplate类的store方法的功能是将文件上传至MongoDB GridFs,该方法接收4个参数,其中第一个参数是一个InputStream类型的对象,第二、第三个参数是可为空值的字符串参数,最后一个参数mongodb的一个对象类型。
这里将本地e:/input.txt文件,上传至MongoDB GridFs,并标记该文件的userId为1.
5、创建一个启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootMongodbDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMongodbDemoApplication.class, args);
}
}
6、启动服务,在浏览器中访问http://localhost:8080/upload
返回success时,说明文件已经成功上传。
可以检查MongoDB Grid中是否存在该文件,通过在命令行中执行以下语句:
mongofiles list --db=spring-boot-mongodb
可以发现input.txt文件已经成功上传至MongoDB GridFs。
7、修改GridController类,添加下载文件功能。
修改完后的CridController类代码如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
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;
@RestController
public class GridController {
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private MongoTemplate mongoTemplate;
@GetMapping("/upload")
public String uploadFile() throws Exception {
File file = new File("e://input.txt");
InputStream content = new FileInputStream(file);
DBObject metadata = new BasicDBObject("userId","1");
ObjectId fileId = gridFsTemplate.store(content, file.getName(),"image/png",metadata);
System.out.println(fileId.toString());
return "success";
}
@GetMapping("/download/{userId}")
public void getFiles(@PathVariable("userId") String userId,HttpServletResponse response) {
try {
GridFSFile gridfs = gridFsTemplate.findOne(Query.query(Criteria.where("metadata.userId").is(userId)));
response.setHeader("Content-Disposition","attachment;filename=\""+gridfs.getFilename()+"\"");
GridFSBucket gridFSBucket = GridFSBuckets.create(mongoTemplate.getDb());
GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridfs.getObjectId());
GridFsResource resource = new GridFsResource(gridfs,gridFSDownloadStream);
InputStream inp = resource.getInputStream();
OutputStream out = response.getOutputStream();
IOUtils.copy(inp,out);
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码解析:
在下载文件接口中@GetMapping("/download/{userId}"),接收一个{userId}作为输入参数,使用了findOne方法根据上传时候给文件标记userId查询MongoDB GridFS上的文件并将输入的{userId}作为查询条件值,该方法返回一个GridFSFile类对象。
setHeader:设置下载文件响应头信息。
GridFSBuckets.create:根据MongoDB数据库名称创建buckets,由于MongoDB GridFS将集合存放在公共的bucket中,所以需要根据数据库名称找到相应的bucket。
gridFSBucket.openDownloadStream(gridfs.getObjectId()):根据查询到记录objectid获取需要下载的文件流。
IOUtils.copy(inp,out):根据输入流复制到输出流,实现下载文件。
重启服务,然后在浏览器中访问http://localhost:8080/download/1
这里1是之前上传文件input.txt,给input.txt标记的userId,现在通过访问下载文件接口,下载input.txt文件。下载效果如下图: