Получение объекта из базы данных, содержащей изображение байтового массива - PullRequest
0 голосов
/ 29 октября 2019

Я работаю над своим блогом и у меня возникли проблемы. Прежде всего, я могу загрузить любое изображение, а затем найти это изображение по id, преобразовать byte [] в String и отобразить его в браузере. У меня просто есть что-то вроде этого

Image imagesObj = imageService.getImage(id); 
byte[] encode = Base64.getEncoder().encode(imagesObj.getImage());
model.addAttribute("image", new String(encode, "UTF-8"));
<img th:src="*{'data:image/jpg;base64,'+ image" alt="#" />

Я получил объекты Post и объекты Image, сопоставленные @OneToOne. Когда я делаю новое сообщение, идентификатор из изображения также присваивается сообщение. Теперь проблема в том, что когда я хочу отобразить все свои сообщения на главной странице с помощью:

 @GetMapping("/")
    public String mainPage(Model model) {
        model.addAttribute("posts", postService.findAll());
        return "main";

    }

Я возвращаю весь объект Post, и он содержит postTitle, postContent и byte [] массив. Я нашел похожую проблему в этом вопросе Как отобразить массив байтов из модели в Thymeleaf Из этого поста я пришел с чем-то вроде этого:

   @GetMapping("image/{id}")
    public void getImageDetails(@PathVariable Long id, HttpServletResponse response) throws IOException {

        response.setContentType("image/jpeg");
        Image image = imageService.getImage(id);
        InputStream is = new ByteArrayInputStream(image.getImage());
        IOUtils.copy(is, response.getOutputStream());
        //IOUtils(is, response.getOutputStream());
    }


Thymeleaf

   <img th:src="@{'image/{id}' + @{post.image()}}" alt="#">

Я пробовал также с post.getImage (). Я думаю об этом в течение некоторого времени, и не знаю, как мне решить эту проблему. Спасибо

ОБНОВЛЕНИЕ

Мне удалось найти решение, но это не очень хороший способ сделать это. Я читаю байты из файла, а затем преобразовываю его в строку и сохраняю изображение как строку в базе данных. Позже, когда я использую findAll(), я могу читать изображение в тимелист.

byte[] image = file.getBytes();
byte[] encodeBase64 = Base64.getEncoder().encode(image);
String s = new String(encodeBase64, "UTF-8");

Сохранение строк в базу данных.

А в Thymeleaf я просто зацикливаюсь на объекте Post и проверяю значения* null

<img  th:src="@{'data:image/jpeg;base64,'+${post?.getImage()?.getImageString()}}" alt="#"/>

Если у вас есть какие-либо советы, чтобы сделать его лучше, пожалуйста, дайте мне сейчас

1 Ответ

0 голосов
/ 31 октября 2019

Вам стоит взглянуть на проект сообщества Spring Content . Этот проект предоставляет вам Spring Data API и подход к разработке контента. Spring Data - это неструктурированные данные (документы, изображения, видео и т. Д.), А структурированные данные. Вы можете добавить его примерно так: -

pom.xml (также доступны стартеры Spring Boot)

   <!-- Java API -->
   <dependency>          
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-jpa</artifactId>
      <version>0.11.0</version>
   </dependency>
   <!-- REST API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest</artifactId>
      <version>0.11.0</version>
   </dependency>

Конфигурация

@Configuration
@EnableJpaStores
@Import("org.springframework.content.rest.config.RestConfiguration.class") <!-- enables REST API)
public class ContentConfig {

   <!-- specify the resource specific to your database --> 
   @Value("/org/springframework/content/jpa/schema-drop-h2.sql")
   private ClasspathResource dropBlobTables;

   <!-- specify the resource specific to your database --> 
   @Value("/org/springframework/content/jpa/schema-h2.sql")
   private ClasspathResource createBlobTables;

   @Bean
   DataSourceInitializer datasourceInitializer() {
     ResourceDatabasePopulator databasePopulator =
            new ResourceDatabasePopulator();

     databasePopulator.addScript(dropBlobTables);
     databasePopulator.addScript(createBlobTables);
     databasePopulator.setIgnoreFailedDrops(true);

     DataSourceInitializer initializer = new DataSourceInitializer();
     initializer.setDataSource(dataSource());
     initializer.setDatabasePopulator(databasePopulator);

     return initializer;
   }
}

Примечание: эта конфигурация не требуется, если вы используете соответствующий стартовый пакет Spring Boot.

Чтобы связать контент, добавьте аннотации Spring Content к вашей сущности Image.

Post.java

@Entity
public class Post {

   ...

   @OneToOne
   private Image image;

Image.java

@Entity
public class Image {

   // replace @Lob/byte array field with:

   @ContentId
   private String contentId;

   @ContentLength
   private long contentLength = 0L;

   @MimeType
   private String mimeType;

Создайте «хранилище» для ваших изображений:

ImageContentStore.java

public interface ImageContentStore extends ContentStore<Image, String> {
}

Это все, что вам нужно для создания конечных точек REST @ /image/{imageId}. Когда ваше приложение запускается, Spring Content проверит ваши зависимости (см. Spring Content JPA / REST), взглянет на ваш ImageContentStore интерфейс и внедрит реализацию этого интерфейса для JPA. Он также внедрит @Controller, который перенаправляет http-запросы в эту реализацию. Это избавляет вас от необходимости реализовывать все это самостоятельно.

Итак ...

curl -X POST /image/{imageId} -F 'data=@path/to/local/file'

сохранит содержимое файла path/to/local/file в базе данных и свяжет его с сущностью post с идентификатором postId.

curl /image/{imageId}

получит его снова и так далее ... поддерживает полную CRUD.

Здесь есть пара руководств и видео по началу работы здесь. Справочное руководство - здесь .

HTH

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...