В этой статье мы увидим, как загружать изображения в базу данных, а также просматривать сведения об изображениях с помощью весенней загрузки.
Предположим, мы разрабатываем приложение, в котором мы хотим хранить профили разных пользователей, и мы также хотим сохранить их изображение профиля/DP в нашем хранилище данных. У нас есть сущность Пользователь, которая содержит основные атрибуты, такие как имя пользователя, полное имя, пароль, адрес и т. д.
Таким образом, более удобным способом является создание другого объекта, назовем его объектом Изображение в нашем приложении и сопоставлением этого объекта с отношением OneToOne с уже существующим объектом Пользователь.
@Entity @Table(name = "image_table") @Getter @Setter @Builder public class Image { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long imageID; private String imageName; private String type; @Lob @Column(name = "picByte", length = 5000) private byte[] picByte; @OneToOne @JoinColumn(name = "users_id", referencedColumnName = "id") private User users_id; //mapping with User entity } }
В этом посте я буду использовать базу данных H2 для простоты, но вы можете использовать любую базу данных по вашему выбору, например MySql, Postgres и т. д.
Теперь создайте ImageRepository, здесь у нас будет один метод для получения изображений из базы данных по имени.
public interface ImageRepo extends JpaRepository<ImageModel,Long> { Optional<ImageModel> findByImageName(String imageName); }
Теперь мы напишем нашу бизнес-логику для загрузки и просмотра изображений в нашем контроллере. Вы также можете написать бизнес-логику, создав отдельный класс службы для изображений.
@RestController public class ImageController { @Autowired ImageRepository imageRepository; @PostMapping("/upload/image") public ResponseEntity<ImageUploadResponse> uplaodImage(@RequestParam("image") MultipartFile file) throws IOException { imageRepository.save(Image.builder() .name(file.getOriginalFilename()) .type(file.getContentType()) .image(ImageUtility.compressImage(file.getBytes())).build()); return ResponseEntity.status(HttpStatus.OK) .body(new ImageUploadResponse("Image uploaded successfully: " + file.getOriginalFilename())); } @GetMapping(path = {"/get/image/info/{name}"}) public Image getImageDetails(@PathVariable("name") String name) throws IOException { final Optional<Image> dbImage = imageRepository.findByName(name); return Image.builder() .name(dbImage.get().getName()) .type(dbImage.get().getType()) .image(ImageUtility.decompressImage(dbImage.get().getImage())).build(); } @GetMapping(path = {"/get/image/{name}"}) public ResponseEntity<byte[]> getImage(@PathVariable("name") String name) throws IOException { final Optional<Image> dbImage = imageRepository.findByName(name); return ResponseEntity .ok() .contentType(MediaType.valueOf(dbImage.get().getType())) .body(ImageUtility.decompressImage(dbImage.get().getImage())); }
Для сжатия и распаковки наших изображений мы создали класс в папке utils.
public class ImageUtility { public static byte[] compressImage(byte[] data) { Deflater deflater = new Deflater(); deflater.setLevel(Deflater.BEST_COMPRESSION); deflater.setInput(data); deflater.finish(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); byte[] tmp = new byte[4*1024]; while (!deflater.finished()) { int size = deflater.deflate(tmp); outputStream.write(tmp, 0, size); } try { outputStream.close(); } catch (Exception e) { } return outputStream.toByteArray(); } public static byte[] decompressImage(byte[] data) { Inflater inflater = new Inflater(); inflater.setInput(data); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); byte[] tmp = new byte[4*1024]; try { while (!inflater.finished()) { int count = inflater.inflate(tmp); outputStream.write(tmp, 0, count); } outputStream.close(); } catch (Exception exception) { } return outputStream.toByteArray(); }
Теперь наш код готов, мы запустим его и протестируем наши API в Postman. Вы можете использовать любую платформу по вашему выбору.
Для тестирования API-интерфейсов image в Postman в разделе Заголовок снимите флажок с автоматически сгенерированного ключа Content-Type и выберите собственный Content-Type со значением multipart/form-data; граница=что-то.
Теперь наш пример готов, теперь мы можем использовать эту концепцию в различных приложениях.
Спасибо за прочтение!!