Reputation: 307
I need to provide a file upload service based Http.
Should I just use the SpringMVC to make a java web project to receive file through controller? Or any advice?
Then what servlet container is preferred to be selected? Tomcat?
Thank you!
Upvotes: 1
Views: 151
Reputation: 2479
You should take a look at the Spring community project called Spring Content.
This project makes it easy to build contentful applications and services. It has the same programming model as Spring Data. Meaning it can supply implementations for the file storage and controller implementations, therefore you don't need to concern yourself with creating these yourself. It is essentially is to content (or unstructured data) what Spring Data is to structured data.
This might look something like the following:-
pom.xml (for Spring Web MVC. Spring Boot also supported)
<!-- Spring Web MVC dependencies -->
...
<!-- Java API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs</artifactId>
<version>0.7.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest</artifactId>
<version>0.7.0</version>
</dependency>
StoreConfig.java
@Configuration
@EnableFilesystemStores
@Import(RestConfiguration.class)
public class EnableFilesystemStoresConfig {
@Bean
File filesystemRoot() {
try {
return new File("/path/to/your/uploaded/files");
} catch (IOException ioe) {}
return null;
}
@Bean
FileSystemResourceLoader fileSystemResourceLoader() {
return new FileSystemResourceLoader(filesystemRoot().getAbsolutePath());
}
}
FileStore.java
@StoreRestResource(path="files")
public interface FileStore extends Store<String> {
}
This is all you need to do to get REST Endpoints that will allow you to store and retrieve files. As mentioned how this actually works is very much like Spring Data. When your application starts Spring Content will see the spring-content-fs
dependency, know that you want to store content on your filesystem and inject a filesystem implementation of the FileStore
interface into the application context. It will also see the spring-content-rest
and inject a controlller (i.e. REST endpoints) that talk to the file store interface. Therefore, you don't have to do any of this yourself.
So, for example:
curl -X POST /files/myfile.pdf -F "file=@/path/to/myfile.pdf"
will store the the file on the filesystem at /path/to/your/uploaded/files/myfile.pdf
And:
curl /files/myfile.pdf
will fetch it again and so on...these endpoints support full CRUD and the GET & PUT endpoints also support video streaming (or byte range-requests).
You could also decide to store the contents elsewhere like in the database with your entities, or in S3 by swapping the spring-content-fs
dependency for the appropriate Spring Content Storage module. Examples for every type of storage are here.
In addition, in case it is helpful, often content is associated with Spring Data Entities. So, it is also possible to have the FileStore interface implement ContentStore, like this:
> FileStore.java
@StoreRestResource(path="files")
public interface FileStore extends ContentStore<File, String> {
}
And to add Spring Content-annotated fields to your Spring Data entities, like this:
> File.java
@Entity
public class File {
@Id
@GeneratedValue
private long id;
...other existing fields...
@ContentId
private String contentId;
@ContentLength
private long contentLength = 0L;
@MimeType
private String mimeType = "text/plain";
...
}
This approach changes the REST endpoints as the content is now addressable via the Spring Data URL. So:
POST /files/{fileId} -F "image=@/some/path/to/myfile.pdf"
will upload myfile.pdf
to /path/to/your/uploaded/files/myfile.pdf
. As it did before but it will also update the fields on the File entity with id fileId
.
GET /files/{fileId}
will get it again.
HTH P.S. Don't be shy about raising issues/features request and/or PRs we are actively looking for engagement.
Upvotes: 2