1. Présentation
Dans ce didacticiel, nous verrons comment télécharger et récupérer des fichiers à l'aide de MongoDB et de Spring Boot.
Nous utiliserons MongoDB BSON pour les petits fichiers et GridFS pour les plus grands.
2. Configuration Maven
Tout d'abord, nous allons ajouter le spring-boot-starter-data-mongodb dépendance à notre pom.xml :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
De plus, nous aurons besoin du spring-boot-starter-web et spring-boot-starter-thymeleaf dépendances pour afficher l'interface utilisateur de notre application. Ces dépendances sont également présentées dans notre Guide de Spring Boot avec Thymeleaf.
Dans ce tutoriel, nous utilisons Spring Boot version 2.x.
3. Propriétés de démarrage du printemps
Ensuite, nous allons configurer les propriétés Spring Boot nécessaires.
Commençons par les propriétés MongoDB :
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=springboot-mongo
Nous allons également définir les propriétés Servlet Multipart pour autoriser le téléchargement de fichiers volumineux :
spring.servlet.multipart.max-file-size=256MB
spring.servlet.multipart.max-request-size=256MB
spring.servlet.multipart.enabled=true
4. Téléchargement de petits fichiers
Nous allons maintenant discuter de la façon de télécharger et de récupérer de petits fichiers (taille <16 Mo) à l'aide de MongoDB BSON .
Ici, nous avons un simple Document classe : Photo. Nous stockerons notre fichier image dans un BSON Binaire :
@Document(collection = "photos")
public class Photo {
@Id
private String id;
private String title;
private Binary image;
}
Et nous aurons un simple PhotoRepository :
public interface PhotoRepository extends MongoRepository<Photo, String> { }
Maintenant, pour le PhotoService , nous n'aurons que deux méthodes :
- addPhoto() — pour télécharger une photo vers MongoDB
- getPhoto() — pour récupérer une Photo avec un identifiant donné
@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. Téléchargement de fichiers volumineux
Maintenant, nous allons utiliser GridFS pour télécharger et récupérer des fichiers volumineux.
Tout d'abord, nous allons définir un simple DTO - Vidéo – pour représenter un gros fichier :
public class Video {
private String title;
private InputStream stream;
}
Similaire au PhotoService , nous aurons un VideoService avec deux méthodes — addVideo() et 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;
}
}
Pour plus de détails sur l'utilisation de GridFS avec Spring, consultez notre article GridFS dans Spring Data MongoDB.
6. Contrôleurs
Voyons maintenant les contrôleurs — PhotoController et VideoController .
6.1. PhotoController
Tout d'abord, nous avons le PhotoController, qui utilisera notre PhotoService pour ajouter/obtenir des photos .
Nous allons définir le addPhoto() méthode pour télécharger et créer une nouvelle 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;
}
Nous avons aussi getPhoto() pour récupérer une Photo avec un identifiant donné :
@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";
}
Notez que, comme nous avons les données d'image renvoyées sous la forme d'un octet[] , nous le convertirons en Base64 Chaîne pour l'afficher sur le front-end.
6.2. Contrôleur vidéo
Ensuite, jetons un coup d'œil à notre VideoController .
Cela aura une méthode similaire, addVideo() , pour mettre en ligne une vidéo à notre 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;
}
Et ici nous avons getVideo() pour récupérer une Vidéo avec un id donné :
@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";
}
Nous pouvons également ajouter un streamVideo() méthode qui créera une URL de diffusion à partir de la vidéo 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. Front-End
Enfin, voyons notre interface.
Commençons par uploadPhoto.html , qui fournit un formulaire simple pour télécharger une image :
<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>
Ensuite, nous ajouterons le photos.html view pour afficher nos photos :
<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>
De même, nous avons le uploadVideo.html pour télécharger une vidéo :
<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>
Et videos.html pour afficher les vidéos :
<html>
<body>
<h1>View Video</h1>
Title: <span th:text="${title}">title</span>
<video width="400" controls>
<source th:src="${url}" />
</video>
</body>
</html>