Sahan.java
Sahan.java

Reputation: 70

Create URL for the uploaded file

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

Answers (3)

Paul Warren
Paul Warren

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

ILya Cyclone
ILya Cyclone

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

CharlieNoodles
CharlieNoodles

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

Related Questions