How do you save files for entity in Spring Data Rest?

為{幸葍}努か 提交于 2020-01-06 08:05:42

问题


In a regular entity for SDR, it takes care of all properties of an entity for you saving it to the database. But how do you handle files?

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

@RepositoryRestResource
public interface UserRepository extends JpaRepository<User, Long> {}

How can I make it so that a User owns a list of files, can upload and download them?


回答1:


I suggest you can use @Lob instead to save file data (fileData variable below)

@Entity
public class File {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    private String fileName;

    private String fileType;

    @Lob
    private byte[] fileData;
}



回答2:


This is not really possible with Spring Data/REST as it focusses on structured data; i.e. tables and associations, for the most part.

@Lob is problematic as it forces you to store your content in the database which isn't necessarily where you want to store it. The file-system or S3 might be better for example.

byte[] is also problematic if you have very large files as you will likely cause OutOfMemoryExceptions.

Instead, there is a community project called Spring Content that addresses exactly the problem you are trying to solve.

Spring Content provides the same programming paradigms as Spring Data/REST for unstructured data; i.e. images, documents, movies, etc. So, using this project you can associate one, or in your case, many "content" objects with your Spring Data entities and manage them over HTTP just like you do with your Spring Data Entities too.

Its pretty simple to add to your project, as follows:

pom.xml (boot starters also available)

   <!-- 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>

Configuration

@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());
   }
}    

To associate content, modify your User entity as follows:

@Entity
public class User {
 String name;
 List<Image> images; 
}

Add an Image entity:

@Entity
public class Image {

  @ContentId
  private String contentId;

  @ContentLength
  private long contentLength = 0L;

  @MimeType
  private String mimeType = "text/plain";
}

And to this add a "store" (the equivalent of a Repository but for content):

ImageStore.java

@StoreRestResource
public interface ImageStore extends FilesystemContentStore<Image, String> {}

This is all you need to create REST endpoints @ /users/{userId}/images. When your application starts, Spring Content will look at your dependencies seeing Spring Content Filesystem, look at your ImageStore interface and inject a filesystem-based implementation of that interface. It will also see the Spring Content REST dependency and inject an @Controller implementation that forwards HTTP requests to your ImageStore. Just like Spring Data does for your UserRepository. This saves you having to implement any of this yourself which I think is what you are after.

So...

To manage content with the injected REST API:

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

will store the image on the filesystem at `` and associate it with the user entity whose id is userId.

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

will fetch it again and so on...supports all CRUD methods and video streaming as well BTW!

There are a couple of getting started guides here. The reference guide for Spring Content Filesystem is here. And there is a tutorial video here. The coding bit starts about 1/2 way through.

A couple of additional points: - if you use the Spring Boot Starters then you don't need the @Configuration for the most part.
- Just like Spring Data is an abstraction, so is Spring Content so you aren't limited to storing your images on the filesystem. You could store them as BLOBs in the database, or in cloud storage like S3.

HTH



来源:https://stackoverflow.com/questions/59585693/how-do-you-save-files-for-entity-in-spring-data-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!