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.
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.
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; } } Test the application
Allow's run the application and test information technology using Postman:
Yay, it works 🎉
If you check the project directory, yous will find the file uploaded.
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:
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 😉
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