как сохранить изображение в Redis с помощью java/spring

Я использую Redis и Spring Framework на своем сервере загрузки изображений. Мне нужно сохранить изображения в Redis. Я нашел следующий вопрос, но он был для python.
как сохранить изображение в Redis с помощью Python / ПИЛ

Я не уверен, что это лучший способ, но я хотел бы знать, как это сделать в java (желательно с использованием Spring Framework). Я использую spring-data-redis, который использует jedis.

Я хотел бы знать, является ли хорошей стратегией хранение изображений в Redis.


person Gene Diaz    schedule 29.07.2013    source источник


Ответы (4)


Redis безопасен для двоичных файлов, поэтому в случае с Jedis вы можете использовать BinaryJedis для хранения двоичных данных так же, как и любые другие значения, которые вы храните в Redis.

И нет, я не думаю, что хранение изображений в Redis и, следовательно, в памяти — это хорошая стратегия. Это должен быть очень особый вариант использования.

person Jahaja    schedule 30.07.2013
comment
Привет! Будет ли облако лучше для хранения изображений? - person vinkovsky; 08.04.2021

Во-первых, Redis — не лучший вариант для хранения изображений. Redis находится в памяти, поэтому размещение файлов, таких как изображения, в памяти не будет хорошим шагом.

Если вы хотите вводить изображения, вы можете использовать их следующим образом.

Ниже приведены шаги

1) сделайте свой maven pom.xml со следующими банками

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
    </dependency>

    <dependency>
           <groupId>org.springframework.data</groupId>
           <artifactId>spring-data-redis</artifactId>
           <version>1.3.0.RELEASE</version>
        </dependency>

            <dependency>
               <groupId>redis.clients</groupId>
               <artifactId>jedis</artifactId>
               <version>2.4.1</version>
            </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.0</version>
    </dependency>

2) сделайте свою конфигурацию xml следующим образом

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
        xmlns:c="http://www.springframework.org/schema/c"
        xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd

        http://www.springframework.org/schema/cache 
        http://www.springframework.org/schema/cache/spring-cache.xsd">



    <bean id="jeidsConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
      p:host-name="localhost" p:port="6379" p:password="" />

     <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
      p:connection-factory-ref="jeidsConnectionFactory" />

     <bean id="imageRepository" class="com.self.common.api.poc.ImageRepository">
      <property name="redisTemplate" ref="redisTemplate"/>
     </bean>

</beans>

3) Сделайте свои классы следующим образом

package com.self.common.api.poc;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class RedisMainApp {

 public static void main(String[] args) throws IOException {
  ApplicationContext applicationContext = new ClassPathXmlApplicationContext("mvc-dispatcher-servlet.xml");
  ImageRepository imageRepository = (ImageRepository) applicationContext.getBean("imageRepository");

  BufferedImage img = ImageIO.read(new File("files/img/TestImage.png"));
  BufferedImage newImg;
  String imagestr;
  imagestr = encodeToString(img, "png");
  Image image1 = new Image("1", imagestr);

  img = ImageIO.read(new File("files/img/TestImage2.png"));
  imagestr = encodeToString(img, "png");
  Image image2 = new Image("2", imagestr);

  imageRepository.put(image1);
  System.out.println(" Step 1 output : " + imageRepository.getObjects());
  imageRepository.put(image2);
  System.out.println(" Step 2 output : " + imageRepository.getObjects());
  imageRepository.delete(image1);
  System.out.println(" Step 3 output : " + imageRepository.getObjects());

 }

 /**
  * Decode string to image
  * @param imageString The string to decode
  * @return decoded image
  */
 public static BufferedImage decodeToImage(String imageString) {

     BufferedImage image = null;
     byte[] imageByte;
     try {
         BASE64Decoder decoder = new BASE64Decoder();
         imageByte = decoder.decodeBuffer(imageString);
         ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
         image = ImageIO.read(bis);
         bis.close();
     } catch (Exception e) {
         e.printStackTrace();
     }
     return image;
 }

 /**
  * Encode image to string
  * @param image The image to encode
  * @param type jpeg, bmp, ...
  * @return encoded string
  */
 public static String encodeToString(BufferedImage image, String type) {
     String imageString = null;
     ByteArrayOutputStream bos = new ByteArrayOutputStream();

     try {
         ImageIO.write(image, type, bos);
         byte[] imageBytes = bos.toByteArray();

         BASE64Encoder encoder = new BASE64Encoder();
         imageString = encoder.encode(imageBytes);

         bos.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
     return imageString;
 }
}

package com.self.common.api.poc;

public class Image implements DomainObject {

 public static final String OBJECT_KEY = "IMAGE";

 public Image() {
 }

 public Image(String imageId, String imageAsStringBase64){
  this.imageId = imageId;
  this.imageAsStringBase64 = imageAsStringBase64;
 }
 private String imageId;
 private String imageAsStringBase64;

 public String getImageId() {
  return imageId;
 }

 public void setImageId(String imageId) {
  this.imageId = imageId;
 }

 public String getImageName() {
  return imageAsStringBase64;
 }

 public void setImageName(String imageAsStringBase64) {
  this.imageAsStringBase64 = imageAsStringBase64;
 }

 @Override
 public String toString() {
  return "User [id=" + imageAsStringBase64 + ", imageAsBase64String=" + imageAsStringBase64 + "]";
 }

 @Override
 public String getKey() {
  return getImageId();
 }

 @Override
 public String getObjectKey() {
  return OBJECT_KEY;
 }
}

package com.self.common.api.poc;

import java.io.Serializable;

public interface DomainObject extends Serializable {

 String getKey();

 String getObjectKey();
}

package com.self.common.api.poc;

import java.util.List;

import com.self.common.api.poc.DomainObject;

public interface Repository<V extends DomainObject> {

 void put(V obj);

 V get(V key);

 void delete(V key);

 List<V> getObjects();
}

package com.self.common.api.poc;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import com.self.common.api.poc.DomainObject;

public class ImageRepository implements Repository<Image>{

 @Autowired
 private RedisTemplate<String,Image> redisTemplate;

 public RedisTemplate<String,Image> getRedisTemplate() {
  return redisTemplate;
 }

 public void setRedisTemplate(RedisTemplate<String,Image> redisTemplate) {
  this.redisTemplate = redisTemplate;
 }

 @Override
 public void put(Image image) {
  redisTemplate.opsForHash()
    .put(image.getObjectKey(), image.getKey(), image);
 }

 @Override
 public void delete(Image key) {
  redisTemplate.opsForHash().delete(key.getObjectKey(), key.getKey());
 }

 @Override
 public Image get(Image key) {
  return (Image) redisTemplate.opsForHash().get(key.getObjectKey(),
    key.getKey());
 }

 @Override
 public List<Image> getObjects() {
  List<Image> users = new ArrayList<Image>();
  for (Object user : redisTemplate.opsForHash().values(Image.OBJECT_KEY) ){
   users.add((Image) user);
  }
  return users;
 }

}

Дополнительные сведения о джедаях sprint можно найти на http://www.javacodegeeks.com/2012/06/using-redis-with-spring.html

Пример кода взят с http://javakart.blogspot.in/2012/12/spring-data-redis-hello-world-example.html

person ravi ranjan    schedule 10.06.2014
comment
Привет! Должен ли я вместо этого использовать облако и получать изображения по URL-адресу? - person vinkovsky; 08.04.2021

Преобразуйте изображение в строку base64 и сохраните его в Redis как пару ключ-значение. Как преобразовать изображение в строку base64, можно найти здесь http://ben-bai.blogspot.in/2012/08/java-convert-image-to-base64-string-and.html

person Global Warrior    schedule 29.07.2013

Взяв подсказку из ответа @global-warrior, вот что я сделал (требуется Java 8):

private String getEncodedString(byte[] bytes) {
    return new String(Base64.getEncoder().encode(bytes));
}

private byte[] getDecodedByteArray(String string) {
    return Base64.getDecoder().decode(string.getBytes());
}

И использовал репозиторий и объект Spring Data Redis для хранения и извлечения:

@RedisHash("image") @Data @AllArgsConstructor
public class RedisImageEntity {
    @Id String checksum;
    String image;
}

public interface RedisImageRepository extends CrudRepository<RedisImageEntity, String> {}

Наконец, в контроллере:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
ResponseEntity<ImageUploadDTO> uploadImage(MultipartFile image) {
    // ...
    redisImageRepository.save(
        new RedisImageEntity(checksum, getEncodedString(image.getBytes))
    );
    // ...
}

@RequestMapping(value = "/image", method = RequestMethod.GET)
ResponseEntity<ImageResponseDTO> getImage(String checksum) {
    // ...
    prepareImage(getDecodedByteArray(
        redisImageRepository.findById(checksum).orElse(null)
    ));
    // ...
}
person aksh1618    schedule 11.09.2019