1. 概述
本教程將介紹如何使用 MongoDB 和 Spring Boot 上傳和檢索文件。
我們將使用 MongoDB 的 BSON 處理小型文件,使用 GridFS 處理大型文件。
2. Maven 配置
首先,我們將 spring-boot-starter-data-mongodb 依賴添加到我們的 pom.xml 文件中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>此外,我們需要 spring-boot-starter-web 和 spring-boot-starter-thymeleaf 依賴項,以便顯示我們應用程序的用户界面。這些依賴項也見於我們的 Spring Boot 與 Thymeleaf 指南。
在本教程中,我們使用的是 Spring Boot 版本 2.x。
3. Spring Boot 屬性配置
接下來,我們將配置必要的 Spring Boot 屬性。
讓我們從 MongoDB 屬性開始:
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=springboot-mongo我們還將設置 Servlet Multipart 屬性,以允許上傳大型文件:
spring.servlet.multipart.max-file-size=256MB
spring.servlet.multipart.max-request-size=256MB
spring.servlet.multipart.enabled=true4. 上傳小型文件
現在,我們將討論如何使用 MongoDB 的 BSON 來上傳和檢索小於 16MB 的小型文件。
這裏我們有一個簡單的 Document 類——Photo。 我們將使用 BSON Binary 存儲我們的圖像文件:
@Document(collection = "photos")
public class Photo {
@Id
private String id;
private String title;
private Binary image;
}我們將會有一個簡單的 PhotoRepository:
public interface PhotoRepository extends MongoRepository<Photo, String> { }現在,對於 <em >PhotoService</em >,我們將只包含兩個方法:
- addPhoto() — 用於將 Photo 上傳到 MongoDB
- getPhoto() — 用於根據給定的 ID 檢索 Photo
@Service
public class PhotoService {
@Autowired
private PhotoRepository photoRepo;
public String addPhoto(String title, MultipartFile file) throws IOException {
Photo photo = new Photo(title);
photo.setImage(
new Binary(BsonBinarySubType.BINARY, file.getBytes()));
photo = photoRepo.insert(photo); return photo.getId();
}
public Photo getPhoto(String id) {
return photoRepo.findById(id).get();
}
}5. 上傳大型文件
現在,我們將使用 GridFS 將大型文件上傳和檢索。
首先,我們將定義一個簡單的 DTO – Video – 以表示大型文件:
public class Video {
private String title;
private InputStream stream;
}類似於 PhotoService,我們將擁有一個 VideoService,該服務包含兩個方法:addVideo() 和 getVideo():
@Service
public class VideoService {
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private GridFsOperations operations;
public String addVideo(String title, MultipartFile file) throws IOException {
DBObject metaData = new BasicDBObject();
metaData.put("type", "video");
metaData.put("title", title);
ObjectId id = gridFsTemplate.store(
file.getInputStream(), file.getName(), file.getContentType(), metaData);
return id.toString();
}
public Video getVideo(String id) throws IllegalStateException, IOException {
GridFSFile file = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id)));
Video video = new Video();
video.setTitle(file.getMetadata().get("title").toString());
video.setStream(operations.getResource(file).getInputStream());
return video;
}
}要了解更多關於使用 GridFS 與 Spring 的信息,請查看我們的 Spring Data MongoDB 上的 GridFS in Spring Data MongoDB 文章。
6. 控制器
現在,讓我們來查看一下控制器——PhotoController 和 VideoController。
6.1. 照片控制器 (PhotoController)
首先,我們有 照片控制器 (PhotoController),它將使用我們的 照片服務 (PhotoService) 來添加/獲取照片。
我們將定義 添加照片 (addPhoto) 方法,用於上傳並創建新的 照片 (Photo):
@PostMapping("/photos/add")
public String addPhoto(@RequestParam("title") String title,
@RequestParam("image") MultipartFile image, Model model)
throws IOException {
String id = photoService.addPhoto(title, image);
return "redirect:/photos/" + id;
}我們還提供 getPhoto() 方法,用於根據給定的 ID 檢索照片:
@GetMapping("/photos/{id}")
public String getPhoto(@PathVariable String id, Model model) {
Photo photo = photoService.getPhoto(id);
model.addAttribute("title", photo.getTitle());
model.addAttribute("image",
Base64.getEncoder().encodeToString(photo.getImage().getData()));
return "photos";
}請注意,由於圖像數據以byte[]形式返回,我們將將其轉換為Base64字符串,以便在前端顯示。
6.2. 視頻控制器
接下來,讓我們來查看我們的 視頻控制器。
這個控制器將具有類似的方法 addVideo(),用於將 視頻 上傳到我們的 MongoDB:
@PostMapping("/videos/add")
public String addVideo(@RequestParam("title") String title,
@RequestParam("file") MultipartFile file, Model model) throws IOException {
String id = videoService.addVideo(title, file);
return "redirect:/videos/" + id;
}以下我們有 getVideo() 函數用於檢索一個具有指定 id 的 Video 對象:
@GetMapping("/videos/{id}")
public String getVideo(@PathVariable String id, Model model) throws Exception {
Video video = videoService.getVideo(id);
model.addAttribute("title", video.getTitle());
model.addAttribute("url", "/videos/stream/" + id);
return "videos";
}我們還可以添加一個 streamVideo() 方法,它將從 Video InputStream 創建一個流式視頻 URL:
@GetMapping("/videos/stream/{id}")
public void streamVideo(@PathVariable String id, HttpServletResponse response) throws Exception {
Video video = videoService.getVideo(id);
FileCopyUtils.copy(video.getStream(), response.getOutputStream());
}7. 前端
最後,讓我們看看我們的前端。
我們先從 uploadPhoto.html 開始,它提供了一個簡單的表單,用於上傳圖片:
<html>
<body>
<h1>Upload new Photo</h1>
<form method="POST" action="/photos/add" enctype="multipart/form-data">
Title:<input type="text" name="title" />
Image:<input type="file" name="image" accept="image/*" />
<input type="submit" value="Upload" />
</form>
</body>
</html>接下來,我們將添加 photos.html 視圖以顯示我們的照片:
<html>
<body>
<h1>View Photo</h1>
Title: <span th:text="${title}">name</span>
<img alt="sample" th:src="*{'data:image/png;base64,'+image}" />
</body>
</html>同樣,我們有 uploadVideo.html 用於上傳 Video:
<html>
<body>
<h1>Upload new Video</h1>
<form method="POST" action="/videos/add" enctype="multipart/form-data">
Title:<input type="text" name="title" />
Video:<input type="file" name="file" accept="video/*" />
<input type="submit" value="Upload" />
</form>
</body>
</html>以及 videos.html 用於顯示視頻:
<html>
<body>
<h1>View Video</h1>
Title: <span th:text="${title}">title</span>
<video width="400" controls>
<source th:src="${url}" />
</video>
</body>
</html>8. 結論
在本文中,我們學習瞭如何使用 MongoDB 和 Spring Boot 上傳和檢索文件。我們使用了 BSON 和 GridFS 兩種方法來上傳和檢索文件。