MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Hochladen und Abrufen von Dateien mit MongoDB und Spring Boot

1. Übersicht

In diesem Tutorial besprechen wir, wie Sie Dateien mit MongoDB und Spring Boot hochladen und abrufen.

Wir verwenden MongoDB BSON für kleine Dateien und GridFS für die Größeren.

2. Maven-Konfiguration

Zuerst fügen wir die spring-boot-starter-data-mongodb hinzu Abhängigkeit zu unserer pom.xml :

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

Außerdem benötigen wir das spring-boot-starter-web und spring-boot-starter-thymeleaf Abhängigkeiten, um die Benutzeroberfläche unserer Anwendung anzuzeigen. Diese Abhängigkeiten werden auch in unserem Leitfaden zu Spring Boot mit Thymeleaf gezeigt.

In diesem Tutorial verwenden wir Spring Boot Version 2.x.

3. Spring Boot-Eigenschaften

Als Nächstes konfigurieren wir die erforderlichen Spring Boot-Eigenschaften.

Beginnen wir mit den MongoDB-Eigenschaften :

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=springboot-mongo

Wir werden auch die Servlet Multipart-Eigenschaften einstellen, um das Hochladen großer Dateien zu ermöglichen:

spring.servlet.multipart.max-file-size=256MB
spring.servlet.multipart.max-request-size=256MB
spring.servlet.multipart.enabled=true

4. Hochladen kleiner Dateien

Jetzt besprechen wir, wie kleine Dateien (Größe <16 MB) mit MongoDB BSON hochgeladen und abgerufen werden .

Hier haben wir ein einfaches Dokument Klasse – Foto. Wir speichern unsere Bilddatei in einem BSON Binär :

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

Und wir werden ein einfaches PhotoRepository haben :

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

Nun zum PhotoService , haben wir nur zwei Methoden:

  • addPhoto() — um ein Foto hochzuladen zu MongoDB
  • getPhoto() — um ein Foto abzurufen mit einer gegebenen ID
@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. Hochladen großer Dateien

Jetzt verwenden wir GridFS zum Hochladen und Abrufen großer Dateien.

Zuerst definieren wir ein einfaches DTO – Video – um eine große Datei darzustellen:

public class Video {
    private String title;
    private InputStream stream;
}

Ähnlich dem PhotoService , haben wir einen VideoService mit zwei Methoden — addVideo() und 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; 
    }
}

Weitere Einzelheiten zur Verwendung von GridFS mit Spring finden Sie in unserem GridFS in Spring Data MongoDB-Artikel.

6. Controller

Werfen wir nun einen Blick auf die Controller – PhotoController und VideoController .

6.1. PhotoController

Zuerst wir haben den PhotoController, die unseren PhotoService verwenden zum Hinzufügen/Abrufen von Fotos .

Wir definieren addPhoto() Methode zum Hochladen und Erstellen eines neuen Fotos :

@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;
}

Wir haben auch getPhoto() um ein Foto mit einer bestimmten ID abzurufen:

@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";
}

Beachten Sie, dass die Bilddaten als Byte[] zurückgegeben werden , konvertieren wir es in ein Base64 Zeichenfolge um es im Frontend anzuzeigen.

6.2. VideoController

Sehen wir uns als Nächstes unseren VideoController an .

Dies wird eine ähnliche Methode haben, addVideo() , um ein Video hochzuladen zu unserer 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;
}

Und hier haben wir getVideo() um ein Video abzurufen mit einer gegebenen id :

@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";
}

Wir können auch ein streamVideo() hinzufügen Methode, die eine Streaming-URL aus dem Video erstellt 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. Frontend

Sehen wir uns zum Schluss unser Front-End an.
Beginnen wir mit uploadPhoto.html , das ein einfaches Formular zum Hochladen eines Bildes bereitstellt:

<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>

Als Nächstes fügen wir die photos.html hinzu Ansicht, um unsere Fotos anzuzeigen:

<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>

Ebenso haben wir die uploadVideo.html um ein Video hochzuladen :

<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>

Und videos.html um Videos anzuzeigen:

<html>
<body>
    <h1>View Video</h1>
    Title: <span th:text="${title}">title</span>
    <video width="400" controls>
        <source th:src="${url}" />
    </video>
</body>
</html>