MongoDBとSpring Bootを使用してファイルをアップロードおよび取得する

1. 概要

このチュートリアルでは、MongoDBとSpring Bootを使用してファイルをアップロードおよび取得する方法について説明します。
*小さなファイルにはMongoDB _BSON_を使用し、大きなファイルには_GridFS_を使用します。*

2. Mavenの構成

最初に、_https://search.maven.org/search?q = g:org.springframework.boot%20AND%20a:spring-boot-starter-data-mongodb [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の依存関係が必要です。 これらの依存関係は、https://www.baeldung.com/spring-boot-crud-thymeleaf [ThymeleafでのSpring Bootのガイド]にも示されています。
このチュートリアルでは、Spring Bootバージョン2.xを使用しています。

3. スプリングブートプロパティ

次に、必要なSpring Bootプロパティを構成します。
  • MongoDBプロパティ*から始めましょう。

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=springboot-mongo
*サーブレットのマルチパートプロパティも設定して、大きなファイルをアップロードできるようにします。*
spring.servlet.multipart.max-file-size=256MB
spring.servlet.multipart.max-request-size=256MB
spring.servlet.multipart.enabled=true

4. 小さなファイルのアップロード

次に、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> { }
これで、_PhotoService_には、2つのメソッドしかありません。
  • 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_には2つのメソッド_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;
    }
}
Springでの_GridFS_の使用の詳細については、https://www.baeldung.com/spring-data-mongodb-gridfs [Spring Data MongoDBのGridFS]の記事をご覧ください。

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;
}
また、特定の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_ _String_に変換してフロントエンドに表示することに注意してください。*

* 6.2 VideoController *

次に、_VideoController_を見てみましょう。
これには、_Video_をMongoDBにアップロードする同様のメソッド_addVideo()_、があります。
@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;
}
そして、ここに、指定された_id_で_Video_を取得する_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";
}
_Video_ _InputStream_からストリーミングURLを作成する_streamVideo()_メソッドを追加することもできます。
@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>
同様に、_Video_をアップロードする_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_の両方を使用して、ファイルをアップロードおよび取得しました。
いつものように、完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-boot-persistence-mongodb[GitHubプロジェクト]で入手できます。