Перейти к основному содержимому

Загружайте и извлекайте файлы с помощью MongoDB и Spring Boot

· 5 мин. чтения

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

Далее мы настроим необходимые свойства 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=true

4. Загрузка небольших файлов

Теперь мы обсудим, как загружать и извлекать небольшие файлы (размером менее 16 МБ) с помощью MongoDB BSON .

Здесь у нас есть простой класс Document — Photo. Мы будем хранить наш файл изображения в двоичном файле BSON `` :

@Document(collection = "photos")
public class Photo {
@Id
private String id;

private String title;

private Binary image;
}

И у нас будет простой PhotoRepository :

public interface PhotoRepository extends MongoRepository<Photo, String> { }

Теперь для PhotoService у нас будет только два метода:

  • addPhoto() — загрузить фото в MongoDB .
  • getPhoto() — получить фото с заданным идентификатором
@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 см. в нашей статье GridFS в Spring Data MongoDB .

6. Контроллеры

Теперь давайте взглянем на контроллеры — PhotoController и VideoController .

6.1. ФотоКонтроллер

Во- первых, у нас есть PhotoController, который будет использовать наш PhotoService для добавления/получения фотографий .

Мы определим метод addPhoto() для загрузки и создания новой фотографии :

@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() для получения фотографии с заданным идентификатором:

@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. ВидеоКонтроллер

Теперь давайте посмотрим на наш VideoController .

У него будет аналогичный метод 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() для получения видео с заданным идентификатором :

@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() , который создаст потоковый URL-адрес из 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. Интерфейс

Наконец, давайте посмотрим на наш интерфейс.

Начнем с 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 для загрузки видео :

<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 для загрузки и извлечения файлов.

Как всегда, полный исходный код доступен в проекте GitHub .