Cách upload và download file ảnh trong Spring Boot

Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu cách upload và download file định dạng ảnh hoặc các định dạng thông thường khác như file text, excel v.v trong spring boot.

Setup

Trước khi bắt đầu thì chúng ta cần khởi tạo project spring boot với những dependency sau:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

Tiếp theo chúng ta sẽ cần định nghĩa một User entity dùng để lưu trữ thông tin đăng ký người dùng, trong đó có thuộc tính photo dùng để lưu ảnh người dùng.

package com.deft.entity;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Table(name = "user")
@Getter
@Setter
@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Column
    private String email;

    @Column
    private String password;

    @Column
    private String photo;
}

Một UserRepository dùng để thao tác với database

package com.deft.repository;

import com.deft.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}

Upload và Download ảnh trong Spring boot

Upload ảnh

Thông thường đối với việc upload ảnh trong spring boot thì chúng ta sẽ sẽ lưu ảnh vào các thư mục static resource và lưu đường dẫn vào database. Khi client có nhu cầu hiển thị hoặc download hình ảnh này thì sẽ gửi request lên server spring boot để nhận về hình ảnh tương ứng.

Mặc định spring boot sẽ tự động thêm các thư mục static resource ở các vị trí sau:

  • /META-INF/resources/
  • /resources/
  • /static/
  • /public/

Đối với các định dạng file gửi lên server sẽ được đặt trong một request có Content-Type là multipart/form-data. Spring hỗ trợ @RequestPart annotation dùng để lấy nội dung dạng file và chuyển đổi sang dạng MultipartFile.

Ảnh mình sẽ lưu trữ tại thư mục static/images đây là static resource được spring boot tự cấu hình sẵn nên chúng ta chỉ việc sử dụng thôi.

@RestController
@RequestMapping("/user")
public class UserController {
    private static final Path CURRENT_FOLDER = Paths.get(System.getProperty("user.dir"));

    @Autowired
    private UserRepository userRepository;

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User create(@RequestParam String email,
                       @RequestParam String password,
                       @RequestParam MultipartFile image) throws IOException {
        Path staticPath = Paths.get("static");
        Path imagePath = Paths.get("images");
        if (!Files.exists(CURRENT_FOLDER.resolve(staticPath).resolve(imagePath))) {
            Files.createDirectories(CURRENT_FOLDER.resolve(staticPath).resolve(imagePath));
        }
        Path file = CURRENT_FOLDER.resolve(staticPath)
                .resolve(imagePath).resolve(image.getOriginalFilename());
        try (OutputStream os = Files.newOutputStream(file)) {
            os.write(image.getBytes());
        }

        User user = new User();
        user.setEmail(email);
        user.setPassword(password);
        user.setPhoto(imagePath.resolve(image.getOriginalFilename()).toString());
        return userRepository.save(user);
    }
}

Trong đoạn code trên sau khi nhận request từ client thì mình sẽ tiến hình lưu ảnh tại static/images nằm trên thư mục hiện tại đang chạy spring boot. 

Các bạn có thể thấy 

private static final Path CURRENT_FOLDER = Paths.get(System.getProperty("user.dir"));

dùng để lấy thư mục hiện tại ở project. Sau khi hoàn tất thì mình sẽ tiến nhành kiểm thử thông qua postman.

Output

Download

Sau khi spring boot xử lý ảnh thành công nó sẽ lưu đường dẫn của ảnh vào database. Để download ảnh chúng ta chỉ cần gửi một GET request lên root server kèm đường dẫn của ảnh.

Tóm lược

Như vậy là chúng ta đã tìm hiểu được cách upload và download file ảnh trong Spring boot với sự hỗ trợ của @RequestPart annotation. Đây cũng là cách mà mình hay áp dụng project có chức năng upload file trong Spring boot.

Mã nguồn được mình công khai trên gitlab nếu có vấn đề gì các bạn có thể vào tham khảo: spring-boot-upload.

https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestPart.html

5 1 vote
Article Rating
Subscribe
Notify of
guest
14 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
14
0
Would love your thoughts, please comment.x
()
x