Is There a New Path When Uploading a File to a Server?

Photo by Anton Nazaretian / Unsplash

Upload files to an application are one of the almost common features for a Web awarding. It wants we practice when we change our profile pic, load a CSV file to perform bulk actions, etc. When edifice a Backend with SpringBoot, implementing it tin be daunting and so we will come across how to do it in this tutorial.

What we volition do

We want to build a Backend Web application where and user tin upload his National ID as a PDF file or a picture in PNG and JPG. Additionally, he should provide his full name and the date of nativity for farther verification.

We take a SpringBoot application on a server, and nosotros desire to upload PDF files and Picture files and store them in a directory on the server. Once the file is uploaded, we need to access it through an URL.

Prerequisites

To follow this tutorial, it is required to have the following tool installed on your reckoner:

  • Java Development Kit 11 or after
  • Maven

Setup the project

We will use the SpringBoot initializer to create the project. The only dependency we need for this project is Spring Web.

Create a SpringBoot project from the initializer
Create a SpringBoot project from the initializer

Click on the push "Generate" to download the project, and open up it in your favorite Coffee IDE; I use IntelliJ from Jetbrains.

If you don't take an IDE you tin can run the command below to install maven dependencies and run the awarding:

          mvn install mvn jump-kicking:run        

Verify the application started on port 8080.

The application started on port 8080
The awarding started on port 8080

Create the service to write the file on the server

Let'south create a bundle called "services" then, create a file called FileStorageService.java and finally add the code beneath:

          package com.tericcabrel.upload.services;  import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import coffee.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cadre.env.Environment; import org.springframework.stereotype.Service; import org.springframework.spider web.multipart.MultipartFile;  @Service public class FileStorageService {    individual final Path fileStorageLocation;    @Autowired   public FileStorageService(Environs env) {     this.fileStorageLocation = Paths.get(env.getProperty("app.file.upload-dir", "./uploads/files"))         .toAbsolutePath().normalize();      endeavour {       Files.createDirectories(this.fileStorageLocation);     } grab (Exception ex) {       throw new RuntimeException(           "Could not create the directory where the uploaded files volition be stored.", ex);     }   }    private String getFileExtension(Cord fileName) {     if (fileName == null) {       render null;     }     String[] fileNameParts = fileName.split("\\.");      return fileNameParts[fileNameParts.length - 1];   }      public String storeFile(MultipartFile file) {     // Normalize file proper noun     String fileName =         new Date().getTime() + "-file." + getFileExtension(file.getOriginalFilename());      try {       // Cheque if the filename contains invalid characters       if (fileName.contains("..")) {         throw new RuntimeException(             "Lamentable! Filename contains invalid path sequence " + fileName);       }        Path targetLocation = this.fileStorageLocation.resolve(fileName);       Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);        return fileName;     } catch (IOException ex) {       throw new RuntimeException("Could not store file " + fileName + ". Please try again!", ex);     }   } }        

In the constructor, we get the upload directory from the configuration file awarding.backdrop and if it is non divers, the value is set to ./uploads/files The directory is created on the server it doesn't be all the same.

The method public String storeFile(MultipartFile file) takes the file uploaded, verify it is valid and finally write it inside the upload directory on the server

Let'southward update the configuration files to set the upload directory. Y'all tin can ascertain the value you want:

          app.file.upload-dir=./uploads/files                  

Create the route to upload the file

Now nosotros will create an endpoint nosotros volition use to upload the file. Allow's create a new package called controllers then, create the file called FileUploadController.java; add the lawmaking beneath:

          package com.tericcabrel.upload.controllers;  import com.tericcabrel.upload.responses.UploadResponse; import com.tericcabrel.upload.services.FileStorageService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.spider web.bind.annotation.RequestParam; import org.springframework.web.bind.note.RestController; import org.springframework.web.multipart.MultipartFile;  @RestController public class FileUploadController {    private concluding FileStorageService fileStorageService;    public FileUploadController(FileStorageService fileStorageService) {     this.fileStorageService = fileStorageService;   }    @PostMapping("/upload")   public ResponseEntity<UploadResponse> uploadFile(       @RequestParam(name = "file", required = false) MultipartFile file,       @RequestParam("fullName") Cord fullName,       @RequestParam("dateOfBirth") String dateOfBirth   ) {       String fileName = fileStorageService.storeFile(file);        UploadResponse uploadResponse = new UploadResponse(fileName, fullName, dateOfBirth);        return ResponseEntity.ok().body(uploadResponse);   } }                  

The road /upload render a response of type UploadResponse located in the package "responses". Beneath is the content of that class.

            parcel com.tericcabrel.upload.responses;  public class UploadResponse {   private final Cord fileName;   private final String fullName;   individual terminal String dateOfBirth;    public UploadResponse(String fileName, Cord fullName, Cord dateOfBirth) {     this.fileName = fileName;     this.fullName = fullName;     this.dateOfBirth = dateOfBirth;   }    public String getDateOfBirth() {     return dateOfBirth;   }    public String getFileName() {     render fileName;   }    public String getFullName() {     return fullName;   } }                      
Content of the file UploadResponse.java within the parcel responses

Test the application

Allow's run the application and test information technology using Postman:

Exam the file upload with Postman

Yay, it works 🎉

If you check the project directory, yous will find the file uploaded.

The file uploaded is visible inside the upload directory
The file uploaded is visible within the upload directory

Access to the file through an URL

Now we want to make the file accessible through the browser; for example, if yous browse http//:localhost:8080/uploads/files/1644067384273-file.png we cannot view the file:

We got a 404 Non found because the server try to detect the endpoint uploads/files inside our routes definition and don't see it.

To make information technology works, nosotros need to tell the server to map the path uploads/files to the upload directory instead ordinarily called a static nugget. Once done, all the content inside volition exist served as raw.

Create a parcel configs then, add a new file called ResourceWebConfig.java; add together the lawmaking below:

          package com.tericcabrel.upload.configs;  import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environs; import org.springframework.spider web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  @Configuration public class ResourceWebConfig implements WebMvcConfigurer {   final Surroundings environment;    public ResourceWebConfig(Environment surroundings) {     this.environment = surround;   }    @Override   public void addResourceHandlers(final ResourceHandlerRegistry registry) {     String location = environment.getProperty("app.file.storage.mapping");      registry.addResourceHandler("/uploads/**").addResourceLocations(location);   } }                  

We get the location of the upload directory on the server from the configuration file and map all the routes starting with "/uploads" to that directory. The remaining thing to do is define the belongings in the configuration file.

The value is different depending on the operating system:

  • For Linux and MacOS users: If the project is located at $Domicile/Desktop/springboot-file-upload, the value to set is:
          app.file.storage.mapping=file:~/Desktop/springboot-file-upload/uploads        
  • For Windows Users: if the project is located on the local disk D at D:/projects/springboot-file-upload , the value to fix is:
          app.file.storage.mapping=file:///D:/projects/springboot-file-upload/uploads        

Note: The text file:/// is not a typo; it volition not work if you don't write like that.

Rerun the application and effort to access the file from the browser now:

View the file uploaded in the browser.
View the file uploaded in the browser.

Wrap up

Nosotros saw how to upload a file on the server and then admission information technology through the browser. It is of import to annotation that it is not recommended to access your data this fashion. Yous should consider Cloud storage like Google Bulldoze and AWS S3.

Y'all can find the code source on the GitHub repository.

Follow me on Twitter or subscribe to my newsletter to not miss the upcoming posts and the tips and tricks I share every week.

Happy to run into you lot soon 😉

adamsraine1937.blogspot.com

Source: https://blog.tericcabrel.com/upload-a-file-to-a-server-with-springboot

0 Response to "Is There a New Path When Uploading a File to a Server?"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel