如何在 Spring Data Rest 中保存实体文件?

ero*_*ppa 1 spring jpa spring-data-rest spring-boot

在 SDR 的常规实体中,它会处理实体的所有属性,以便您将其保存到数据库中。但是你如何处理文件呢?

@Entity
public class User {
 String name;
 Set<File> myfiles; //how can I make this work? 
}

@RepositoryRestResource
public interface UserRepository extends JpaRepository<User, Long> {}
Run Code Online (Sandbox Code Playgroud)

我怎样才能让用户拥有文件列表,可以上传和下载它们?

Pau*_*ren 5

这对于 Spring Data/REST 来说是不可能的,因为它专注于结构化数据;大多数情况下,即表和关联。

@Lob是有问题的,因为它迫使您将内容存储在数据库中,而数据库不一定是您想要存储的位置。例如,文件系统或 S3 可能更好。

byte[]如果您有非常大的文件,这也是有问题的,因为您可能会导致 OutOfMemoryExceptions。

相反,有一个名为Spring Content的社区项目可以准确解决您要解决的问题。

Spring Content 为非结构化数据提供了与 Spring Data/REST 相同的编程范例;即图像、文档、电影等。因此,使用此项目,您可以将一个或在您的情况下将多个“内容”对象与您的 Spring Data 实体关联起来,并通过 HTTP 管理它们,就像您对 Spring Data 实体所做的那样。

添加到您的项目非常简单,如下所示:

pom.xml(启动启动器也可用)

   <!-- Java API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-fs</artifactId>
      <version>1.0.0.M4</version>
   </dependency>
   <!-- REST API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest</artifactId>
      <version>1.0.0.M4</version>
   </dependency>
Run Code Online (Sandbox Code Playgroud)

配置

@Configuration
@EnableFilesystemStores
@Import("org.springframework.content.rest.config.RestConfiguration.class")
public class ContentConfig {

   @Bean
   FileSystemResourceLoader fileSystemResourceLoader() throws IOException {
    return new FileSystemResourceLoader(new File("/path/to/uploaded/files").getAbsolutePath());
   }
}    
Run Code Online (Sandbox Code Playgroud)

要关联内容,请修改您的用户实体,如下所示:

@Entity
public class User {
 String name;
 List<Image> images; 
}
Run Code Online (Sandbox Code Playgroud)

添加图像实体:

@Entity
public class Image {

  @ContentId
  private String contentId;

  @ContentLength
  private long contentLength = 0L;

  @MimeType
  private String mimeType = "text/plain";
}
Run Code Online (Sandbox Code Playgroud)

并为此添加一个“存储”(相当于存储库,但用于内容):

图像存储库.java

@StoreRestResource
public interface ImageStore extends FilesystemContentStore<Image, String> {}
Run Code Online (Sandbox Code Playgroud)

这就是创建 REST 端点 @ 所需的全部内容/users/{userId}/images。当您的应用程序启动时,Spring Content 将查看您的依赖项(查看 Spring Content 文件系统),查看您的ImageStore接口并注入该接口的基于文件系统的实现。它还会看到 Spring Content REST 依赖项并注入一个@Controller实现,将 HTTP 请求转发到您的ImageStore. 就像 Spring Data 为您的UserRepository. 这使您不必自己实现任何这些,我认为这就是您所追求的。

所以...

要使用注入的 REST API 管理内容:

curl -X POST /users/{userId}/images-F 文件=@/path/to/image.jpg

会将图像存储在文件系统上的 ``并将其与 id 为 的用户实体关联起来userId

curl /users/{userId}/images/{contentId} -H "Accept: image/jpeg"

将再次获取它等等...支持所有 CRUD 方法和视频流以及顺便说一句!

这里有一些入门指南。Spring内容文件系统的参考指南在这里这里有一个教程视频。编码位大约从 1/2 处开始。

还有几点: - 如果您使用 Spring Boot Starters,那么大多数情况下您不需要 @Configuration。
- 就像 Spring Data 是一个抽象一样,Spring Content 也是一个抽象,因此您不限于将图像存储在文件系统上。您可以将它们作为 BLOB 存储在数据库中或存储在 S3 等云存储中。

华泰