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 users 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)// Query the corresponding file UserFile getFilesById(Integer id) according to the corresponding Id// Update void update (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@Transactionalpublic 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;@Servicepublic class UserFileServiceImpl implements UserFileService { @Autowired private UserFileMapper userFileMapper; /** * * @param id User ID * @ return the 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) { //Determine whether the file is a picture by performing three eye operation 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;@Configurationpublic class ShiroConfig { //Shirofilterfactorybean @ bean public shirofilterfactorybean getshirofilterfactorybean (@ qualifier ("securitymanager") defaultwebsecuritymanager defaultwebsecuritymanager) {shirofilterfactorybean bean = new shirofilterfactorybean(); / / set security manager bean.setSecurityManager(defaultWebSecurityManager) ; // Add Shiro's built-in filter / * anon: you can access authc without authentication: you must be authenticated to access user: you must have the remember me function to use perms: you can access a role only if you have permission to a resource * / map < string, String> filterChainDefinitionMap = new LinkedHashMap<>(); // Indicates that all paths under / file must pass the 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;//User defined userrealmpublic class userrealm extensions authorizingream {@ Autowired userservice; / / authorize @ override protected authorizationinfo dogetauthorizationinfo (principalcollection) {return null;}// Authentication @ override protected authenticationinfo dogetauthenticationinfo (authenticationtoken authenticationtoken) throws authenticationexception {usernamepasswordtoken usertoken = (usernamepasswordtoken) authenticationtoken; / / find user information according to user name 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's 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 "> login < / button > < / div > < div class =" UI error Mini message "> < / div > < div class =" UI Mini negative message "th: none =" ${#strings.isempty (message)} "Th: text =" ${message} "> wrong user name 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: 'please enter username'}]}, password: {identifier: 'password', rules: [{type: 'empty', prompt: 'please enter 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 > file original name < / td > < td > file new name < / td > < td > file suffix < / td > < td > storage path < / td > < td > file size < / td > < td > type < / td > < td > whether to download pictures < / td > < td > < td > > Times < / 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: add a class style -- > <! -- without changing the class attribute in the label< 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 'means / 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})} means / 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}" > <-- Note that name="aaa" should correspond to background MultipartFile aaa -- > < input type = "file" name="aaa" > < input type = "submit" value = "upload file" > < / form > <-- Th: if has an inverse attribute, 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 the current user subject subject = securityutils getSubject(); // Encapsulate the user's login data UsernamePasswordToken token = new UsernamePasswordToken(username, DigestUtils.md5DigestAsHex(password.getBytes()))// Execute the login method. If there is no exception, the execution succeeds. Try {subject. Login (token); return "redirect: / file / showall";} Catch (unknownaccountexception E) {/ / indicates that the user name does not have attributes.addFlashAttribute("message", "wrong user name or password"); return "redirect:/user";} Catch (incorrectcredentialsexception E) {/ / indicates a password error. 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 user = (user) session in the logged in session getAttribute("user"); List<UserFile> files = userFileService. getFilesByUserId(user.getId()); model. addAttribute("files",files); return "showAll"; } // Process uploaded files and save file information to the database @ postmapping ("/ upload") public string upload (multipartfile AAA, httpsession, redirectattributes) throws IOException {if (AAA. Getcontenttype(). Equals ("application / octet stream")) {system.out.println (1); attributes.addflashattribute( "ErrorMessage", "cannot upload empty file!");} else {/ / get the currently logged in object User user = (User) session.getAttribute("user"); / / get the original name of the file String oldFileName = aaa.getOriginalFilename(); / / get the suffix 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(); // Processing directory generated by date 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();}// Handle 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 the file into the database userfileservice SaveFile(userFile); } return "redirect:/file/showAll"; } // File download @ getmapping ("/ download") public void download (integer Id, string openstyle, httpservletresponse response) throws IOException {/ / get the file information userfile userfile = userfileservice.getfilesbyid (Id); / / judge whether the user is opening or downloading online (attachment download if openstyle is attachment, online open if openstyle is inline)) openstyle = openstyle = = null? "Attachment": openstyle; if ("attachment". Equals (openstyle)) {/ / update file download times userfile.setdowncounts (userfile. Getdowncounts()) +1); userFileService. update(userfile); } // Obtain the file input stream string realpath = resourceutils according to the file name and file storage path in the file information getURL("classpath:"). getPath() + "/static" + userfile. getPath(); // Get the 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 the file information @ getmapping ("/ delete") public string delete (integer Id) throws FileNotFoundException {/ / query the information userfile userfile = userfileservice. Getfilesbyid (Id); / / delete the 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 userfileservice. In the database 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: 8081spring: thymeleaf: # close thymeleaf Cache for easy 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 sets the size of a single file, and Max request size = 100MB sets the total size of the file requested for a single time # if you want to not limit the size of the file uploaded, Then set both values to - 1 servlet: multipart: max file size: 10MB Max request size: 100MB mybatis: # mybatis configuration file location config location: classpath: mybatis / mybatis config XML # mapper locations 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".