File upload and download case based on SpringBoot and Mybatis
This case is based on the actual combat of the [bad programmer] enterprise file upload and download project based on SpringBoot and Mybatis. BiliBili link: https://www.bilibili.com/video/BV1764y1u7gn?p=1
Effect achieved
1. Users need to log in first. We use shiro authentication to log in
2. After logging in, the information uploaded by the user is displayed
Project structure directory
step
1. Create a new database
Here we use Navicat to create the files database. The database has two tables: user table and uploaded file record table:
2. Create a springboot project
After the springboot project is created, the dependencies such as thymeleaf, web, lombok, shiro, etc. are introduced. The specific project is POM The XML file is as follows:
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.zq</groupId> <artifactId>files</artifactId> <version>0.0.1-SNAPSHOT</version> <name>files</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.5.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3. Write dao entity class
We create two entity classes, User and UserFile, under the dao package of the project. Here we use lombok to simplify the code. The specific code is as follows:
User.java
package com.zq.dao; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; @Data @AllArgsConstructor @NoArgsConstructor @ToString public class User { private Integer id; // User id private String userName;// user name private String password;// User password }
UserFile.java
package com.zq.dao; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; @Data @AllArgsConstructor @NoArgsConstructor @ToString public class UserFile { private Integer id; // id private String oldFileName;// Initial name of uploaded file private String newFileName;// Upload file new name private String ext;// file extension private String path;// File path private String size;// file size private String type;// file type private String isImg;// Is it a picture private int downCounts;// amount of downloads private Date uploadTime;// Upload time private int userId;// User id }
4. Write dao interface
We create two dao interfaces, UserMapper and UserFileMapper, under the mapper package of the project. The specific code is as follows:
UserMapper.java
package com.zq.mapper; import com.zq.dao.User; public interface UserMapper { /*User login*/ User login(String username,String password); /*Query user by user name*/ User findUserByName(String username); }
UserFileMapper.java
package com.zq.mapper; import com.zq.dao.UserFile; import java.util.List; public interface UserFileMapper { //Query all files of the user by Id List<UserFile> getFilesByUserId(Integer id); //Save file information void SaveFile(UserFile userFile); //Query the corresponding file by Id UserFile getFilesById(Integer id); //to update void update(UserFile userFile); //Delete record by Id void delete(Integer id); }
5. Prepare mapper file
We create UserMapper and UserFileMapper xml files under mapper under mybatis in the resources directory of the project. The specific codes are as follows:
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zq.mapper.UserMapper"> <!--User login--> <select id="login" resultType="com.zq.dao.User"> select * from t_user where username=#{username} and password=#{password} </select> <!--Query users by user name--> <select id="findUserByName" resultType="com.zq.dao.User"> select * from t_user where username=#{username} </select> </mapper>
UserFileMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zq.mapper.UserFileMapper"> <!-- According to user ID Query all the stored files of the user --> <select id="getFilesByUserId" resultType="com.zq.dao.UserFile"> select * from t_files where userId=#{id} </select> <!-- Save file --> <insert id="SaveFile"> INSERT INTO t_files VALUES (#{id}, #{oldFileName},#{newFileName},#{ext}, #{path},#{size},#{type},#{isImg}, #{downCounts},#{uploadTime},#{userId}); </insert> <!-- According to the corresponding file id Query file --> <select id="getFilesById" resultType="com.zq.dao.UserFile"> select * from t_files where id = #{id} </select> <!-- Number of downloads of update files --> <update id="update"> update t_files set downCounts = #{downCounts} where id = #{id} </update> <!--according to Id Delete record--> <delete id="delete"> delete from t_files where id = #{id} </delete> </mapper>
6. Write service
Two service interfaces, UserService and UserFileService, are created under the service package of our project. The specific code is as follows:
UserService.java
package com.zq.service; import com.zq.dao.User; public interface UserService { /*Sign in*/ User login(String username,String password); /*Query user information according to user name*/ User findUserByName(String username); }
UserFileService.java
package com.zq.service; import com.zq.dao.UserFile; import java.util.List; public interface UserFileService { //Query all corresponding file information according to userId List<UserFile> getFilesByUserId(Integer id); //Save user information void SaveFile(UserFile userFile); //Query the corresponding file according to the corresponding Id UserFile getFilesById(Integer id); //to update void update(UserFile userFile); void delete(Integer id); }
Then create an Impl package under the service package, and create two interface implementation classes, UserServiceImpl and UserFileServiceImpl, to implement the methods in the UserService and UserFileService interfaces. The specific code is as follows:
UserServiceImpl.java
package com.zq.service.Impl; import com.zq.dao.User; import com.zq.mapper.UserMapper; import com.zq.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; /** * * @param username user name * @param password password * @return User information */ @Override public User login(String username, String password) { return userMapper.login(username, password); } /** * * @param username user name * @return User information */ @Override public User findUserByName(String username) { return userMapper.findUserByName(username); } }
UserFileServiceImpl.java
package com.zq.service.Impl; import com.zq.dao.UserFile; import com.zq.mapper.UserFileMapper; import com.zq.service.UserFileService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; import java.util.List; @Service public class UserFileServiceImpl implements UserFileService { @Autowired private UserFileMapper userFileMapper; /** * * @param id User id * @return File upload list corresponding to the user */ @Override public List<UserFile> getFilesByUserId(Integer id) { return userFileMapper.getFilesByUserId(id); } /** * * @param userFile Upload information */ @Override public void SaveFile(UserFile userFile) { //Conduct three eye operation to judge whether the file is a picture String isImg = userFile.getType().startsWith("image")?"yes":"no"; System.out.println(isImg); userFile.setIsImg(isImg); userFile.setDownCounts(0); userFile.setUploadTime(new Date()); userFileMapper.SaveFile(userFile); } /** * * @param id Upload file id * @return */ @Override public UserFile getFilesById(Integer id) { return userFileMapper.getFilesById(id); } /** * * @param userFile Upload information */ @Override public void update(UserFile userFile) { userFileMapper.update(userFile); } /** * * @param id Upload file id */ @Override public void delete(Integer id) { userFileMapper.delete(id); } }
7. Write shiro configuration file
Because we want to use shiro for user login authentication, we need to write shiro configuration information (those who don't know shiro can go to my shiro blog first, SpringBoot integrated Shiro learning (Part 1) ), we create new ShiroConfig and UserRealm files under the config of the project. ShiroConfig is used to configure shiro, while UserRealm is a custom realm, which is used to realize user login authentication and authorization. The specific code is as follows:
ShiroConfig.java
package com.zq.config; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { //ShiroFilterFactoryBean @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //Set up security manager bean.setSecurityManager(defaultWebSecurityManager); //Add Shiro's built-in filter /* anon: Access without authentication authc: Authentication is required to access user: You must have the remember me function to use perms: You must have permission on a resource to access it role: You must have a role permission to access */ Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>(); // Indicates that all paths under / file must pass authentication filterChainDefinitionMap.put("/file/*","authc"); bean.setFilterChainDefinitionMap(filterChainDefinitionMap); // Set the default login interface bean.setLoginUrl("/user"); return bean; } //DefaultWebSecurityManager @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //Associate UserRealm securityManager.setRealm(userRealm); return securityManager; } //To create a realm object, you need to customize the class @Bean public UserRealm userRealm(){ return new UserRealm(); } }
UserRealm.java
package com.zq.config; import com.zq.dao.User; import com.zq.service.UserService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.session.Session; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; //Custom UserRealm public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; //to grant authorization @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } //authentication @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken; // Find user information by user name User user = userService.findUserByName(userToken.getUsername()); if (user == null){ //Indicates that the user name is entered incorrectly return null; } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); session.setAttribute("user", user); //authentication return new SimpleAuthenticationInfo("",user.getPassword(),""); } }
8. Preparation of front-end documents
Two html files, Login and showAll, are created under templates in the resources directory of our project. The ui framework used in our front end is semantic ui, Semantic UI document address , the specific code of the html file is as follows:
Login.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>User login interface</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css"> <link rel="stylesheet" th:href="@{/css/me.css}" href="../static/css/me.css"> </head> <body> <div class="m-container-small m-padded-tb-massive" style="max-width: 30em !important;"> <div class="ui container"> <div class="ui middle aligned center aligned grid"> <div class="column"> <h2 class="ui teal image header"> <div class="content"> Welcome to the user file management system </div> </h2> <form class="ui large form" method="post" action="#" th:action="@{/user/login}"> <div class="ui segment"> <div class="field"> <div class="ui left icon input"> <i class="user icon"></i> <input type="text" name="username" placeholder="user name"> </div> </div> <div class="field"> <div class="ui left icon input"> <i class="lock icon"></i> <input type="password" name="password" placeholder="password"> </div> </div> <button class="ui fluid large teal submit button">Sign in</button> </div> <div class="ui error mini message"></div> <div class="ui mini negative message" th:unless="${#strings. Isempty (message)} "th: text =" ${message} "> wrong username and password < / div > </form> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.2/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script> <script> $('.ui.form').form({ fields : { username : { identifier: 'username', rules: [{ type : 'empty', prompt: 'enter one user name' }] }, password : { identifier: 'password', rules: [{ type : 'empty', prompt: 'Please input a password' }] } } }); </script> </body> </html>
showAll.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>User file list page</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css"> </head> <body> <h2>welcome:<span th:text="${session.user.userName}"></span></h2> <table class="ui celled table"> <thead> <tr> <th colspan="11">File list</th> </tr> </thead> <tbody> <tr> <td>ID</td> <td>Original file name</td> <td>File new name</td> <td>file extension</td> <td>Storage path</td> <td>file size</td> <td>type</td> <td>Picture</td> <td>amount of downloads</td> <td>Upload time</td> <td>operation</td> </tr> <tr th:each="file : ${files}"> <td th:text="${file.id}">1</td> <td th:text="${file.oldFileName}">aa.txt</td> <td th:text="${file.newFileName}">uuid.txt</td> <td th:text="${file.ext}">.txt</td> <td th:text="${file.path}">/files</td> <td th:text="${file.size}">1024</td> <td th:text="${file.type}">text/plain</td> <!-- th:classappend:Without changing the label class Property, add a class style--> <!-- <td th:text="${file.isImg}" th:classappend="${file.getIsImg()=='yes'}?'':'negative'">no</td>--> <!-- ${#servletContext.contextPath} get project name @{/} Get project name --> <td> <!-- <img th:if="${file.getIsImg()=='yes'}" style="width: 100px" th:src="${#servletContext.contextPath} + ${file.path} + '/' + ${file.newFileName}">--> <img th:if="${file.getIsImg()=='yes'}" style="width: 100px" th:src="${file.path} + '/' + ${file.newFileName}"> <span th:if="${file.getIsImg()!='yes'}" th:text="${file.isImg}"></span> </td> <td th:text="${file.downCounts}">11</td> <td th:text="${#dates.format(file.uploadTime,'yyyy-MM-dd-HH:mm:ss')}">2020-12-12</td> <td> <a th:href="@{/file/download(id=${file.id})}" href="">download</a> <!--@{/file/download(id=${file.id},openStyle='inline' express /file/download?id=${file.id}?openStyle='inline'--> <a target="_blank" th:href="@{/file/download(id=${file.id},openStyle='inline')}" href="">Open online</a> <!--@{/file/delete(id=${file.id})}express /file/delete?id=file.id --> <a th:href="@{/file/delete(id=${file.id})}" href="">delete</a> </td> </tr> </tbody> </table> <hr> <h3>Upload file</h3> <form method="post" enctype="multipart/form-data" th:action="@{/file/upload}"> <!--be careful name="aaa" To communicate with the background MultipartFile aaa corresponding--> <input type="file" name="aaa"> <input type="submit" value="Upload file"> </form> <!-- th:if There is an inverse property, th:unless,Unless --> <div class="ui small compact negative message" th:unless="${#strings.isEmpty(errorMessage)}" th:text="${errorMessage}"></div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.2/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script> </body> </html>
9. Write controller
We create two controllers, UserController and UserFileController, under the controller package of the project. The specific code is as follows:
UserController.java
package com.zq.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @Controller @RequestMapping("/user") public class UserController { /*Jump to login interface*/ @GetMapping public String loginPage(){ return "Login"; } /*Login processing*/ @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password, RedirectAttributes attributes) { //Get current user Subject subject = SecurityUtils.getSubject(); //Encapsulate user login data UsernamePasswordToken token = new UsernamePasswordToken(username, DigestUtils.md5DigestAsHex(password.getBytes())); //Execute the login method. If there is no exception, the execution is successful try { subject.login(token); return "redirect:/file/showAll"; } catch (UnknownAccountException e) { //Indicates that the user name does not exist attributes.addFlashAttribute("message","Wrong user name or password"); return "redirect:/user"; } catch (IncorrectCredentialsException e){ //Indicates that the password is incorrect attributes.addFlashAttribute("message","Wrong user name or password"); return "redirect:/user"; } } }
UserFileController.java
package com.zq.controller; import com.zq.dao.User; import com.zq.dao.UserFile; import com.zq.service.UserFileService; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.ResourceUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.*; import java.net.URL; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.UUID; @Controller @RequestMapping("/file") public class UserFileController { @Autowired private UserFileService userFileService; /*Display all files uploaded by the current login user*/ @GetMapping("/showAll") public String findAll(HttpSession session, Model model){ //Get the Id in the logged in session User user = (User) session.getAttribute("user"); List<UserFile> files = userFileService.getFilesByUserId(user.getId()); model.addAttribute("files",files); return "showAll"; } //Process the uploaded files and save the file information to the database @PostMapping("/upload") public String upload(MultipartFile aaa, HttpSession session, RedirectAttributes attributes) throws IOException { if (aaa.getContentType().equals("application/octet-stream")){ System.out.println(1); attributes.addFlashAttribute("errorMessage","Cannot upload empty file!"); }else { //Gets the currently logged in object User user = (User) session.getAttribute("user"); //Gets the original name of the file String oldFileName = aaa.getOriginalFilename(); //Gets the suffix of the file String extension = "." + FilenameUtils.getExtension(aaa.getOriginalFilename()); //Generate a new file name String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + UUID.randomUUID().toString().replace("-","").substring(6) + extension; //Get file size long size = aaa.getSize(); //file type String type = aaa.getContentType(); //The process generates directories based on dates String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/files"; String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); String dateDirPath = realPath + "/" + format; // /E:/Desktop/File-Upload/target/classes/static/files/2021-12-21 System.out.println(dateDirPath); File dataDir = new File(dateDirPath); /*If the directory does not exist, create it*/ if (!dataDir.exists()){ dataDir.mkdirs(); } //Process file upload aaa.transferTo(new File(dataDir,newFileName)); UserFile userFile = new UserFile(); userFile.setOldFileName(oldFileName); userFile.setNewFileName(newFileName); userFile.setExt(extension); userFile.setSize(String.valueOf(size)); userFile.setType(type); userFile.setPath("/files/"+format); userFile.setUserId(user.getId()); //Save file to database userFileService.SaveFile(userFile); } return "redirect:/file/showAll"; } //File download @GetMapping("/download") public void download(Integer id,String openStyle,HttpServletResponse response) throws IOException { //Get file information UserFile userfile = userFileService.getFilesById(id); //Judge whether users open or download online (attachment download if openStyle is attachment, online open if openStyle is inline)) openStyle = openStyle == null ? "attachment" : openStyle; if ("attachment".equals(openStyle)){ //Update file downloads userfile.setDownCounts(userfile.getDownCounts()+1); userFileService.update(userfile); } //Obtain the file input stream according to the file name in the file information and the file storage path String realpath = ResourceUtils.getURL("classpath:").getPath() + "/static" + userfile.getPath(); //Get file input stream FileInputStream is = new FileInputStream(new File(realpath, userfile.getNewFileName())); //If openStyle is attachment, it is attachment download; if openStyle is inline, it is online open) response.setHeader("content-disposition",openStyle+";fileName="+ URLEncoder.encode(userfile.getOldFileName(),"UTF-8")); //Get response output stream ServletOutputStream os = response.getOutputStream(); //File copy IOUtils.copy(is,os); IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); } //Delete file information @GetMapping("/delete") public String delete(Integer id) throws FileNotFoundException { //Query information by Id UserFile userFile = userFileService.getFilesById(id); //Delete file String realpath = ResourceUtils.getURL("classpath:").getPath() + "/static" + userFile.getPath(); File file = new File(realpath, userFile.getNewFileName()); if (file.exists()){ file.delete();//Delete now } //Delete discipline from database userFileService.delete(id); return "redirect:/file/showAll"; } }
10. Prepare project configuration file
We write the application of the project YML configuration file, the specific code is as follows:
application.yml
server: port: 8081 spring: thymeleaf: # Close thymeleaf cache to facilitate testing cache: false datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/files?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 username: root password: 123456 #Set the size of the uploaded file # Max file size = 10MB is to set the size of a single file, and Max request size = 100MB is to set the total size of a single requested file #If you want to not limit the size of file upload, set both values to - 1 servlet: multipart: max-file-size: 10MB max-request-size: 100MB mybatis: # mybatis profile location config-location: classpath:mybatis/mybatis-config.xml # mapper location mapper-locations: classpath:mybatis/mapper/*.xml
11. Prepare project startup class and start
We write the startup class of the project. The specific code is as follows:
FilesApplication.java
package com.zq; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.zq.mapper") public class FilesApplication { public static void main(String[] args) { SpringApplication.run(FilesApplication.class, args); } }
Then we start the project,
After launching the project successfully, we enter it in the browser http://localhost:8081/user You can enter the project login page to log in,
After logging in, the information uploaded by the user is displayed
File saving location after successful upload:
Source code acquisition
So far, our case of file upload and download based on SpringBoot and Mybatis has been explained. Source code and database files can be obtained by paying attention to my WeChat official account, I love learning, hee hee, reply to the keyword "file upload and download case".