CodeJava Coding Your Passion
Learn Spring framework:
Spring Boot File Upload Tutorial (Upload and Display Images)DetailsWritten by Nam Ha MinhLast Updated on 20 September 2020 | Print Email 1. Update Database table and for Entity classWe need to update the users table in the database, adding a new column that stores the file name. Say, the column name is photos:The data type is varchar(64) so the column can store file name containing up to 64 characters. Then we need to update corresponding entity class User as follows:@Entity @Table(name = "users") public class User { @Column(nullable = true, length = 64) private String photos; // other fields and getters, setters are not shown }2. Update Web Form for File UploadNext, we need to update the create new user form to add a file input as follows:<form th:action="@{/users/save}" th:object="${user}" method="post" enctype="multipart/form-data" > ... <div> <label>Photos: </label> <input type="file" name="image" accept="image/png, image/jpeg" /> </div> ... </form>Note that we must set the attribute enctype=multipart/form-data form the form tag, to tell the browser that this form may contain file upload. And we restrict that only image files can be uploaded using the accept attribute:<input type="file" name="image" accept="image/png, image/jpeg" />In case you want to allow uploading any files, do not use this attribute.3. Update Spring Controller to Handle File UploadOn the server side with Spring Boot, we need to update the handler method that is responsible to handle form submission as follows:@Controller public class UserController { @Autowired private UserRepository repo; @PostMapping("/users/save") public RedirectView saveUser(User user, @RequestParam("image") MultipartFile multipartFile) throws IOException { String fileName = StringUtils.cleanPath(multipartFile.getOriginalFilename()); user.setPhotos(fileName); User savedUser = repo.save(user); String uploadDir = "user-photos/" + savedUser.getId(); FileUploadUtil.saveFile(uploadDir, fileName, multipartFile); return new RedirectView("/users", true); } }To handle file uploaded from the client, we need to declare this parameter for the handler method:@RequestParam("image") MultipartFile multipartFileThe @RequestParam annotation and MultipartFile interface come from the following packages:import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile;That means we dont have to use any external library for handling file upload. Just use the spring starter web dependency is enough. Under the hood, Spring will use Apache Commons File Upload that parses multipart request to reads data from the file uploaded.Next, we get the name of the uploaded file, set it to the photos field of the User object, which is then persisted to the database:String fileName = StringUtils.cleanPath(multipartFile.getOriginalFilename()); user.setPhotos(fileName); User savedUser = service.save(user);The class StringUtils come from the package org.springframework.util. Note that we store only the file name in the database table, and the actual uploaded file is stored in the file system:String uploadDir = "user-photos/" + savedUser.getId(); FileUploadUtil.saveFile(uploadDir, fileName, multipartFile);Here, the uploaded file is stored in the directory user-photos/userID, which is relative to the applications directory. And below is the code of the FileUploadUtil class:package net.codejava; import java.io.*; import java.nio.file.*; import org.springframework.web.multipart.MultipartFile; public class FileUploadUtil { public static void saveFile(String uploadDir, String fileName, MultipartFile multipartFile) throws IOException { Path uploadPath = Paths.get(uploadDir); if (!Files.exists(uploadPath)) { Files.createDirectories(uploadPath); } try (InputStream inputStream = multipartFile.getInputStream()) { Path filePath = uploadPath.resolve(fileName); Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING); } catch (IOException ioe) { throw new IOException("Could not save image file: " + fileName, ioe); } } }As you can see, this utility class is only responsible for creating the directory if not exists, and save the uploaded file from MultipartFile object to a file in the file system.4. Display uploaded images in browserIn case of uploaded files are images, we can display the images in browser with a little configuration. We need to expose the directory containing the uploaded files so the clients (web browsers) can access. Create a configuration file with the following code:package net.codejava; import java.nio.file.Path; import java.nio.file.Paths; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { exposeDirectory("user-photos", registry); } private void exposeDirectory(String dirName, ResourceHandlerRegistry registry) { Path uploadDir = Paths.get(dirName); String uploadPath = uploadDir.toFile().getAbsolutePath(); if (dirName.startsWith("../")) dirName = dirName.replace("../", ""); registry.addResourceHandler("/" + dirName + "/**").addResourceLocations("file:/"+ uploadPath + "/"); } }Here, we configure Spring MVC to allow access to the directory user-photos in the file system, with mapping to the applications context path as /user-photos.Add a new getter in the entity class User as follows:@Entity public class User { @Transient public String getPhotosImagePath() { if (photos == null || id == null) return null; return "/user-photos/" + id + "/" + photos; } }Then in the view (HTML with Thymeleaf), we can display an image like this:<img th:src="/@{${user.photosImagePath}}" />Thats how to implement file upload functionality for an existing Spring Boot application. And in case of images, you learned how to display the images in the browser. To summarize, here are the key points:
Related Tutorials:
Other Spring Boot Tutorials:
About the Author:Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.Add comment
Show Notify me of follow-up comments Send Cancel Comments12345678 #37Andre2022-01-29 19:53 Hi Nam I'm having the same error I can't show the images in the browser, Does this code still work or do you have to make any modifications? Quote#36Nam2022-01-13 19:23 Hi Lộc, QuoteJust remove the first / before @. Somehow it was added by the CMS software - it was not there intentionally. #35Nguyễn Hữu Lộc2022-01-13 08:31 mình có sử dụng đoạn code trên để show ảnh lên nhưng bị lỗi, bạn hướng dẫn mình được ko? QuoteCaused by: org.attoparser.ParseException: Could not parse as expression: "/@{${user.photosImagePath}}" (template: "user" - line 46, col 8) #34randhir Kumar2021-12-24 22:47 This is so bad if I need different path then how I will manage it will not work Quote#33Kácio de Sousa Menes2021-12-16 07:24 Hello, could you send me the code of this project to my email please Quotekacio.sousagmail.com 12345678 Refresh comments list |