首页 > 解决方案 > 从包含字节数组图像的数据库中获取对象

问题描述

我正在写我的博客,但遇到了一些问题。首先,我可以上传任何图像,然后通过 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。当我发布新帖子时,来自 Image 的 id 也会分配给 Post。现在的问题是,当我想在主页上显示我的所有帖子时:

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

    }

我将返回整个 Post 对象,它包含 postTitle、postContent 和 byte[] 数组。我在这个问题上发现了类似的问题How to display byte array from a model in 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());
    }


百里香叶

   <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");

将 String 保存到数据库。

在 Thymeleaf 中,我只是遍历 Post 对象并检查值是否不为空

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

如果您有任何提示可以让它变得更好,请现在告诉我

标签: javaspringthymeleaf

解决方案


您应该看看社区项目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;

图像.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在数据库中,并将其与 id 为的 post 实体相关联postId

curl /image/{imageId}

将再次获取它等等...支持完整的 CRUD。

这里有一些入门指南和视频。参考指南在这里

高温高压


推荐阅读