使用Springboot整合GridFS實(shí)現(xiàn)文件操作
GridFsOperations,實(shí)現(xiàn)GridFS文件上傳下載刪除
最近學(xué)習(xí)GridFS,想用它整合springboot弄個(gè)文件的上傳下載。
網(wǎng)上查到的很多資料都是使用GridFsTemplate,還有GridFSBucket來(lái)實(shí)現(xiàn)的,需要各種額外配置Bean。但是看了spring-data-mongodb的官方文檔,以及示例代碼,他們只用到了GridFsOperations,無(wú)需其他任何配置。
然后就用GridFsOperations寫(xiě)了個(gè)文件上傳下載的demo,用起來(lái)還是很方便的,給大家個(gè)參考。
上傳下載刪除功能實(shí)現(xiàn)
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
application.properties
#文件上傳下載配置 spring.servlet.multipart.max-file-size=1024MB spring.servlet.multipart.max-request-size=1024MB
FileController
package com.example.tryRedis.controller;
import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.gridfs.GridFsCriteria.*;
import com.mongodb.client.gridfs.model.GridFSFile;
import io.swagger.v3.oas.annotations.Parameter;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.gridfs.GridFsOperations;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/file")
public class FileController {
@Autowired
GridFsOperations gridFsOperations;
//上傳文件
@PostMapping(value = "/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Map<String , ObjectId> upload(@Parameter @RequestPart(value = "file") MultipartFile file){
//開(kāi)始時(shí)間
long begin = System.nanoTime();
Map<String,ObjectId> map = new HashMap<>();
try{
InputStream streamForUpload = file.getInputStream();
ObjectId objectId = gridFsOperations.store(streamForUpload,file.getOriginalFilename(),file.getContentType());
//上傳結(jié)束
long end = System.nanoTime();
long time = end-begin;
System.out.println("本次上傳共耗時(shí): "+ time);
System.out.println("上傳成功!文件名: "+file.getOriginalFilename()+". 文件ID: "+objectId);
map.put(file.getOriginalFilename(),objectId);
}catch (Exception e){
e.printStackTrace();
}
return map;
}
//查詢并下載文件
@GetMapping("/download")
public String download(String filename, HttpServletResponse response) throws IOException {
//開(kāi)始時(shí)間
long begin = System.nanoTime();
//查詢文件
GridFSFile result = gridFsOperations.findOne(query(whereFilename().is(filename)));
GridFsResource gridFsResource= gridFsOperations.getResource(result);
String contentType = gridFsResource.getContentType();
System.out.println("contentType: "+contentType);
System.out.println("filename: "+gridFsResource.getFilename());
response.reset();
response.setContentType(contentType);
//注意: 如果沒(méi)有下面這行設(shè)置header, 結(jié)果會(huì)將文件的內(nèi)容作為響應(yīng)的 body 直接輸出在頁(yè)面上, 而不是下載文件
response.setHeader("Content-Disposition","attachment;filename="+filename); //指定下載文件名
ServletOutputStream outputStream = response.getOutputStream();
InputStream is = gridFsResource.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len=is.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
is.close();
outputStream.close();
//下載結(jié)束
long end = System.nanoTime();
long time = end-begin;
System.out.println("本次下載共耗時(shí): "+ time);
return contentType;
}
@DeleteMapping("/delete")
public String deleteFile(@Parameter @RequestParam("filename") String filename){
gridFsOperations.delete(query(whereFilename().is(filename)));
return "delete success";
}
}
測(cè)試
上傳

下載
紅色圈內(nèi)點(diǎn)擊download就可以下載啦?;蛘咴诘刂窓谥苯虞斎雔ocalhost:8080/file/download?filename=todo.txt 也可以直接下載文件(這里的todo.txt是我測(cè)試的文件,你們填自己上傳的文件名,不要忘了加上后綴名!)

刪除

上面這些上傳刪除功能測(cè)試的時(shí)候,大家也可以結(jié)合mongodb的數(shù)據(jù)庫(kù)去看看。

上傳的文件類(lèi)型不限,大小嘛,看你properties文件里設(shè)置的上限是多大了。我拿700MB的文件上傳了也ok,然后在數(shù)據(jù)庫(kù)中會(huì)被分成很多個(gè)塊進(jìn)行存儲(chǔ)。具體存儲(chǔ)的細(xì)節(jié)和原理,網(wǎng)上文檔很多,這兒就不嘮叨嘞。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis自定義類(lèi)型轉(zhuǎn)換器實(shí)現(xiàn)加解密
這篇文章主要介紹了MyBatis自定義類(lèi)型轉(zhuǎn)換器實(shí)現(xiàn)加解密的相關(guān)資料,需要的朋友可以參考下2016-07-07
Mybatis中Collection集合標(biāo)簽的使用詳解
這篇文章主要介紹了Mybatis中Collection集合標(biāo)簽的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Java中的HashMap和Hashtable區(qū)別解析
這篇文章主要介紹了Java中的HashMap和Hashtable區(qū)別解析,HashMap和Hashtable都實(shí)現(xiàn)了Map接口,但決定用哪一個(gè)之前先要弄清楚它們之間的區(qū)別,主要的區(qū)別有線程安全性、同步和速度,需要的朋友可以參考下2023-11-11
Java 語(yǔ)言守護(hù)線程 Daemon Thread使用示例詳解
這篇文章主要為大家介紹了Java 語(yǔ)言守護(hù)線程 Daemon Thread使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
mybatis使用foreach查詢不出結(jié)果也不報(bào)錯(cuò)的問(wèn)題
這篇文章主要介紹了mybatis使用foreach查詢不出結(jié)果也不報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03

