1. Ikhtisar
Dalam tutorial ini, kita akan membahas cara mengunggah dan mengambil file menggunakan MongoDB dan Spring Boot.
Kami akan menggunakan MongoDB BSON untuk file kecil dan GridFS untuk yang lebih besar.
2. Konfigurasi Maven
Pertama, kita akan menambahkan spring-boot-starter-data-mongodb ketergantungan pada pom.xml our kami :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Selain itu, kita memerlukan spring-boot-starter-web dan spring-boot-starter-thymeleaf dependensi untuk menampilkan antarmuka pengguna aplikasi kita. Dependensi ini juga ditampilkan di Panduan kami untuk Boot Musim Semi dengan Thymeleaf.
Dalam tutorial ini, kami menggunakan Spring Boot versi 2.x.
3. Properti Boot Musim Semi
Selanjutnya, kita akan mengonfigurasi properti Spring Boot yang diperlukan.
Mari kita mulai dengan properti MongoDB :
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=springboot-mongo
Kami juga akan menyetel properti Servlet Multipart untuk mengizinkan pengunggahan file besar:
spring.servlet.multipart.max-file-size=256MB
spring.servlet.multipart.max-request-size=256MB
spring.servlet.multipart.enabled=true
4. Mengunggah File Kecil
Sekarang, kita akan membahas cara mengunggah dan mengambil file kecil (ukuran <16MB) menggunakan MongoDB BSON .
Di sini, kami memiliki Dokumen sederhana kelas — Foto. Kami akan menyimpan file gambar kami di BSON Biner :
@Document(collection = "photos")
public class Photo {
@Id
private String id;
private String title;
private Binary image;
}
Dan kita akan memiliki PhotoRepository simple sederhana :
public interface PhotoRepository extends MongoRepository<Photo, String> { }
Sekarang, untuk PhotoService , kita hanya memiliki dua metode:
- tambahkanFoto() — untuk mengunggah Foto ke MongoDB
- getPhoto() — untuk mengambil Foto dengan id yang diberikan
@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. Mengunggah File Besar
Sekarang, kita akan menggunakan GridFS untuk mengunggah dan mengambil file besar.
Pertama, kita akan mendefinisikan DTO sederhana – Video – untuk mewakili file besar:
public class Video {
private String title;
private InputStream stream;
}
Mirip dengan Layanan Foto , kami akan memiliki Layanan Video dengan dua metode — addVideo() dan 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;
}
}
Untuk detail selengkapnya tentang menggunakan GridFS dengan Spring, periksa GridFS kami di artikel Spring Data MongoDB.
6. Pengontrol
Sekarang, mari kita lihat pengontrolnya — PhotoController dan Pengendali Video .
6.1. Pengendali Foto
Pertama, kami memiliki PhotoController, yang akan menggunakan PhotoService kami untuk menambahkan/mendapatkan foto .
Kami akan mendefinisikan addPhoto() metode untuk mengunggah dan membuat Foto baru :
@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;
}
Kami juga memiliki getPhoto() untuk mengambil Foto dengan id yang diberikan:
@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";
}
Perhatikan bahwa karena kami memiliki data gambar yang dikembalikan sebagai byte[] , kami akan mengonversinya menjadi Base64 Tali untuk menampilkannya di front-end.
6.2. Pengendali Video
Selanjutnya, mari kita lihat VideoController our .
Ini akan memiliki metode serupa, addVideo() , untuk mengupload Video ke MongoDB kami:
@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;
}
Dan di sini kita memiliki getVideo() untuk mengambil Video dengan id yang diberikan :
@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";
}
Kami juga dapat menambahkan streamVideo() metode yang akan membuat URL streaming dari Video InputStream :
@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. Tampilan Depan
Terakhir, mari kita lihat front-end kita.
Mari kita mulai dengan uploadPhoto.html , yang menyediakan formulir sederhana untuk mengunggah gambar:
<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>
Selanjutnya, kita akan menambahkan photos.html view untuk menampilkan foto kita:
<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>
Demikian pula, kami memiliki uploadVideo.html untuk mengunggah 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>
Dan videos.html untuk menampilkan video:
<html>
<body>
<h1>View Video</h1>
Title: <span th:text="${title}">title</span>
<video width="400" controls>
<source th:src="${url}" />
</video>
</body>
</html>