Reputation: 70
I am creating a simple web application using spring mvc. In this application i wrote code for the upload file to the server('target' folder).Files are upload to the server without any problem. Now i want create a URL for uploaded file that can access the file directly using the URL. How can i do this?
This is the code for the upload file to the server.
@PutMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public boolean saveFile(@RequestPart("file") MultipartFile myFile) {
System.out.println(myFile.getOriginalFilename());
try {
String projectPath = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getAbsolutePath();
File uploadDir = new File(projectPath + "/uploads");
uploadDir.mkdir();
System.out.println(uploadDir.getAbsolutePath());
myFile.transferTo(new File(uploadDir.getAbsolutePath() + "/" + myFile.getOriginalFilename()));
System.out.println("File Path " + uploadDir.getAbsolutePath() + "/" + myFile.getOriginalFilename());
String imgUrl = "../../../../../BackEnd/target/POS-1.0.0/WEB-INF/classes/uploads/" + myFile.getOriginalFilename();
System.out.println(imgUrl);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Upvotes: 0
Views: 1576
Reputation: 2479
Another option is to use Spring Content. It has several advantages over the other solutions; it provides controller and service implementations for you, so you don't have to implement them yourself. Provides an abstraction over the storage allowing you to refactor your solution without changing code. For example, you could move your solution to the cloud and use something like S3 for your storage. It can allow be paired with other projects Spring Data (for capturing additional metadata about your content) and Apache Solr (for searching inside the documents) that overall will give you a much richer application.
It is pretty easy to add to your application.
pom.xml
<!-- Java API -->
<!-- just change this depdendency if you want to store somewhere else -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs</artifactId>
<version>0.6.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest</artifactId>
<version>0.6.0</version>
</dependency>
StoreConfig.java
@Configuration
// just change this annotation if you want to store somewhere else
@EnableFilesystemStores
@Import(RestConfiguration.class)
public class EnableFilesystemStoresConfig {
@Bean
File filesystemRoot() {
try {
return new File("/path/to/your/files");
} catch (IOException ioe) {}
return null;
}
@Bean
FileSystemResourceLoader fileSystemResourceLoader() {
return new FileSystemResourceLoader(filesystemRoot().getAbsolutePath());
}
}
NB: and even easier if you are using Spring Boot.
FileStore.java
@StoreRestResource(path="files")
public interface FileStore extends Store<String> {
}
And that's it. The FileStore is essentially a generic Spring ResourceLoader. The spring-content-fs
dependency will cause Spring Content to inject a filesystem-based implementation so you don't need to worry about implementing it yourself. Moreover, the spring-content-rest
dependency will cause Spring Content to also inject an implementation if an @Controller
that forwards HTTP requests onto the method of the FileStore
.
So you will now have a fully functional (POST, PUT, GET, DELETE) REST-based file service at /files
that will use your FileStore
to retrieve (and store) files in /path/to/your/files
on your server.
So:
GET /files/some/file.csv
will download file.csv
from /path/to/your/files/some/
.
And...
curl --upload-file some-other-file.csv /files/some-other-file.csv
will upload some-other-file.csv
and store it in /path/to/your/files/
on your server.
HTH
Upvotes: 0
Reputation: 964
You might also use builtin server feature to map urls to file system. Depends on specific application or web server you use.
For Tomcat look for such configuration in server.xml:
<Context docBase="/my/files/folder" path="/get-file" />
And no coding needed at all!
Upvotes: 0
Reputation: 356
Because of we don't know the type of file you want to return, you can use a RAW return:
@GetMapping(value = "/get-file/{filename}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public byte[] getFile(@PathVariable String filename) throws IOException {
File file = new File(
"../../../../../BackEnd/target/POS-1.0.0/WEB-INF/classes/uploads/" + filename);
InputStream inputStream = new FileInputStream(file);
return IOUtils.toByteArray(inputStream);
}
The IOUtils.toByteArray(inputStream)
method come from the overly used Apache commons IO library:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
Upvotes: 1