В этой статье мы увидим, как загружать изображения в базу данных, а также просматривать сведения об изображениях с помощью весенней загрузки.

Предположим, мы разрабатываем приложение, в котором мы хотим хранить профили разных пользователей, и мы также хотим сохранить их изображение профиля/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; граница=что-то.

Теперь наш пример готов, теперь мы можем использовать эту концепцию в различных приложениях.

Спасибо за прочтение!!