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