java - 从包含字节数组图像的数据库中获取对象
问题描述
我正在写我的博客,但遇到了一些问题。首先,我可以上传任何图像,然后通过 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="#"/>
如果您有任何提示可以让它变得更好,请现在告诉我
解决方案
您应该看看社区项目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。
高温高压
推荐阅读
- ios - 隐藏导航控制器搜索栏并以编程方式打开大标题
- java - 在不丢失对象引用的情况下内联调用 setter
- angular - 如何在每个按钮单击时将数据附加到列表中:Angular typescript + Laravel
- elasticsearch - Logstash:使用日志文件的行号作为 document_id
- ios - 字符串匹配正则表达式模式,但通过范围提取子字符串后返回结果为零
- amazon-web-services - 实现预定推送通知的最佳方式
- c# - 在 Process.StandardOutput 中获取和设置位置
- grails - Grails 3.3.8 不会重新加载对项目所做的更改
- freeswitch - 具有 10 位以上正则表达式验证的免费 Switch?
- sql-server - 如果 DDL 触发器中不支持条件