sql >> Databasteknik >  >> NoSQL >> MongoDB

Ladda upp och hämta filer med MongoDB och Spring Boot

1. Översikt

I den här handledningen kommer vi att diskutera hur man laddar upp och hämtar filer med MongoDB och Spring Boot.

Vi kommer att använda MongoDB BSON för små filer och GridFS för de större.

2. Maven-konfiguration

Först lägger vi till spring-boot-starter-data-mongodb beroende av vår pom.xml :

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

Dessutom behöver vi spring-boot-starter-webben och spring-boot-starter-thymeleaf beroenden för att visa användargränssnittet för vår applikation. Dessa beroenden visas också i vår guide till fjäderstövel med Thymeleaf.

I den här handledningen använder vi Spring Boot version 2.x.

3. Spring Boot Properties

Därefter kommer vi att konfigurera de nödvändiga Spring Boot-egenskaperna.

Låt oss börja med MongoDB-egenskaperna :

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

Vi kommer också att ställa in egenskaperna för Servlet Multipart för att tillåta uppladdning av stora filer:

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

4. Ladda upp små filer

Nu ska vi diskutera hur man laddar upp och hämtar små filer (storlek <16 MB) med MongoDB BSON .

Här har vi ett enkelt Dokument klass — Foto. Vi lagrar vår bildfil i en BSON Binär :

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

Och vi kommer att ha ett enkelt PhotoRepository :

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

Nu, för Fototjänsten , vi har bara två metoder:

  • addPhoto() — för att ladda upp ett foto till MongoDB
  • getPhoto() — för att hämta ett foto med ett givet 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. Ladda upp stora filer

Nu kommer vi att använda GridFS för att ladda upp och hämta stora filer.

Först kommer vi att definiera en enkel DTO – Video – för att representera en stor fil:

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

Liknar Fototjänst , kommer vi att ha en Videotjänst med två metoder — addVideo() och 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; 
    }
}

För mer information om hur du använder GridFS med Spring, kolla vår GridFS in Spring Data MongoDB-artikel.

6. Styrenheter

Låt oss nu ta en titt på kontrollerna – PhotoController och VideoController .

6.1. PhotoController

Först, har vi PhotoController, som kommer att använda vår Fototjänst för att lägga till/få foton .

Vi kommer att definiera addPhoto() metod för att ladda upp och skapa ett nytt foto :

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

Vi har också getPhoto() för att hämta ett foto med ett givet id:

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

Observera att eftersom vi har returnerat bilddata som en byte[] konverterar vi den till en Base64 Sträng för att visa den i front-end.

6.2. Videokontroll

Låt oss sedan ta en titt på vår VideoController .

Detta kommer att ha en liknande metod, addVideo() , för att ladda upp en video till vår 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;
}

Och här har vi getVideo() för att hämta en Video med ett givet 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";
}

Vi kan också lägga till en streamVideo() metod som skapar en strömmande URL från 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. Front-end

Till sist, låt oss se vårt gränssnitt.
Låt oss börja med uploadPhoto.html , som ger ett enkelt formulär för att ladda upp en bild:

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

Därefter lägger vi till photos.html visa för att visa våra foton:

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

På samma sätt har vi uploadVideo.html för att ladda upp en 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>

Och videos.html för att visa videor:

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

  1. Mongoose, hitta, returnera specifika egenskaper

  2. Itererar över en mongodb-markör i serie (väntar på återuppringningar innan du går till nästa dokument)

  3. Kan jag ställa in global TTL i redis?

  4. skapa snabbt ett exempel på en hbase-tabell