SpringBoot realizes file upload ①

File upload is an essential part in web development. Such as avatar uploading, adding goods, uploading pictures and so on... Is the process of uploading and saving files to the server.

Implementation steps

01. Construction project

Build a SpringBoot project

<?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.6.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.qd</groupId>
    <artifactId>uploadDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>uploadDemo</name>
    <description>File upload demo</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
server:
  port: 8082 # Application port

spring:
  # freemarker
  freemarker:
    suffix: .html
    cache: false
  # File upload configuration
  servlet:
    multipart:
      # Enable http upload processing
      enabled: true
      # Maximum length of a single file
      max-file-size: 2MB
      # Maximum requested file size
      max-request-size: 10MB
      # Set temporary directory
      # location: F://data//temp

02. Prepare file upload page

Add an upload.html page in resources/templates /

package com.qd.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * Create by IntelliJ IDEA
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/21 21:01
 */
@Controller
public class UploadController {

    @GetMapping("/upload")
    public String toUpload() {
        return "upload";
    }
}

03. Background implementation

UploadService

package com.qd.service;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * File upload
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/21 21:20
 */
@Service
public class UploadService {

    /**
     * MultipartFile Object is the class of file upload and receive provided by spring MVC
     * File upload underlying principle request. Getinputstream()
     *
     * @param multipartFile
     * @param dir
     * @return
     */
    public String uploadImg(MultipartFile multipartFile, String dir) {

        // 1: Specify the directory where files are uploaded
        File targetFile = new File("D:\\tmp\\" + dir);

        try {
            // 2: If targetFile does not exist, create
            if (!targetFile.exists()) targetFile.mkdirs();
            // 3: Specify the directory after file upload
            File targetFileName = new File(targetFile, "1.png"); // Write dead first
            // 4: Upload the file to the specified directory
            multipartFile.transferTo(targetFileName);
            return "ok";
        } catch (IOException e) {
            e.printStackTrace();
            return "fail";
        }
    }
}

UploadController

package com.qd.controller;

import com.qd.service.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

/**
 * Create by IntelliJ IDEA
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/21 21:01
 */
@Controller
public class UploadController {

    @Autowired
    private UploadService uploadService;


    @GetMapping("/upload")
    public String toUpload() {
        return "upload";
    }

    @PostMapping("/upload/file")
    @ResponseBody
    public String upload(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {

        // 1: Null judgment
        if (multipartFile.isEmpty()) {
            return "The file is empty!!!";
        }

        multipartFile.getSize();//Get size
        multipartFile.getOriginalFilename();//Get file name
        String contentType = multipartFile.getContentType();//Get file type

        // 2: Determine whether the document conforms to
        if (!"image/png".equals(contentType) || !"image/jpg".equals(contentType)) {
            return "File format does not match";
        }

        // 3: Gets the folder specified by the user
        // Purpose: for isolation, different businesses and different files are put into different directories
        String dir = request.getParameter("dir");
        return uploadService.uploadImg(multipartFile, dir);
    }
}

web page

    <h2>File upload</h2>
    <form action="/upload/file" method="post" enctype="multipart/form-data">
        <input type="text" name="dir" value="avatar" hidden>
        <input type="file" name="file" accept="image/png,image/jpg">
        <input type="submit" value="Click me to upload">
    </form>

result

04. Background improvement

There are also problems in the above. For example, the name of the uploaded file is written dead, and the directory page should be divided according to the level of year, month and day

package com.qd.service;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * File upload
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/21 21:20
 */
@Service
public class UploadService {

    /**
     * MultipartFile Object is the class of file upload and receive provided by spring MVC
     * File upload underlying principle request. Getinputstream()
     *
     * @param multipartFile
     * @param dir
     * @return
     */
    public String uploadImg(MultipartFile multipartFile, String dir) {

        try {
            // 1: Real file name
            String originalFilename = multipartFile.getOriginalFilename(); // Uploaded file aa.jpg
            // 2: Intercepted file name.jpg
            String imgSuffix = originalFilename.substring(originalFilename.lastIndexOf(".")); // Get. jpg
            // 3: Generate a unique file name
            String newFileName = UUID.randomUUID().toString() + imgSuffix;  // Randomly generated, such as dfasf42432.jpg
            // 4: Isolate files as directories
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date()); // Date Directory: November 21, 2021
            // 5: Upload directory of final documents
            File targetFile = new File("D:\\tmp\\" + dir, datePath); // Final directory generated; D://tmp/avatar/2021/11/21
            // 6: If dirFile does not exist, it is created
            if (!targetFile.exists()) targetFile.mkdirs();
            // 7: Specify the full file name after the file is uploaded
            File dirFileName = new File(targetFile, newFileName); // The final path of the file on the server is D://tmp/avatar/2021/11/21/dfasf42432.jpg
            // 8: File upload
            multipartFile.transferTo(dirFileName);
            return "ok";
        } catch (IOException e) {
            e.printStackTrace();
            return "fail";
        }
    }
}

result

05. Front desk improvement

At present, the front-end needs to select the uploaded picture first, and then click the upload button to upload it. Can you improve it so that you can automatically upload as long as you select the picture?

    <h2>File upload</h2>
    <form action="/upload/file" id="uploadform" method="post" enctype="multipart/form-data">
        <input type="text" name="dir" value="avatar" hidden>
        <input type="file" name="file" accept="image/png,image/jpg" onchange="upload()">
        <!--<input type="submit" value="Click me to upload">-->
    </form>

    <script>
        function upload() {
            console.log("Select a picture to upload~")
            document.getElementById("uploadform").submit();
        }
    </script>

ok ~ you can learn from the local single file upload here. Then we encounter another problem: how to get the uploaded pictures? Then we will solve this problem.

get files

File accessible path: http://localhost:8082/avatar/2021/11/21/dfasf42432.jpg

	// 9: Accessible path http://localhost:8082/avatar/2021/11/21/dfasf42432.jpg
	String fileName = dir + "/" + datePath + "/" + newFileName;
	return fileName;


However, it is still inaccessible at this time. How to solve it—— Upload to the server directory, that is, the webapps / directory under the current tomcat server

How does SpringBoot specify any directory as the access directory of resources?

We know that SpringBoot has a directory static. The files in this directory can be accessed directly through http requests, but the program will be turned into a jar package and the files cannot be written. Therefore, SpringBoot provides a resource directory mapping mechanism. Next, let's try.

01. Create a new configuration class

package com.qd.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Static resource mapping configuration class
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/22 5:50
 */
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    // Additional static resource configuration for profile upload
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //  registry.addResourceHandler("/ resource access path"). addResourceLocations("mapping directory");
        registry.addResourceHandler("/uploadImg/**").addResourceLocations("file:D://tmp//");
    }
}

Analysis: if you upload files to the D://tmp directory, you can http://localhost:8082/uploadImg/aa.jpg visit. Access test

ok, there's still a problem at this stage. We wrote addResourceLocations("file:D://tmp / /"). Think about it. What if it's a linux system? Should we continue to improve.

02. Improvement

Improvement of WebMvcConfiguration configuration class

package com.qd.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Static resource mapping configuration class
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/22 5:50
 */
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Value("${file.staticPatterPath}")
    private String staticPatterPath;
    @Value("${file.uploadFolder}")
    private String uploadFolder;
    
    // Additional static resource configuration for profile upload
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //  registry.addResourceHandler("/ resource access path"). addResourceLocations("mapping directory");
        registry.addResourceHandler(staticPatterPath + "**").addResourceLocations("file:" + uploadFolder);
    }
}

Create a new yml file for environment isolation

# Native configuration
file:
  rootPath: http://localhost:8082
  staticPatterPath: /uploadImg/
  uploadFolder: D:/tmp/


# Server configuration
file:
  rootPath: https://www.xxx.com
  staticPatterPath: /uploadImg/
  uploadFolder: /www/upload/

Improve service

package com.qd.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * File upload
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/21 21:20
 */
@Service
public class UploadService {

    // Root path
    @Value("${file.rootPath}")
    private String rootPath;
    // Mapping directory
    @Value("${file.uploadFolder}")
    private String uploadFolder;
    // Access path to the resource
    @Value("${file.staticPatterPath}")
    private String staticPatterPath;

    /**
     * MultipartFile Object is the class of file upload and receive provided by spring MVC
     * File upload underlying principle request. Getinputstream()
     *
     * @param multipartFile
     * @param dir
     * @return
     */
    public String uploadImg(MultipartFile multipartFile, String dir) {

        try {
            // 1: Real file name
            String originalFilename = multipartFile.getOriginalFilename(); // Uploaded file aa.jpg
            // 2: Intercepted file name.jpg
            String imgSuffix = originalFilename.substring(originalFilename.lastIndexOf(".")); // Get. jpg
            // 3: Generate a unique file name
            String newFileName = UUID.randomUUID().toString() + imgSuffix;  // Randomly generated, such as dfasf42432.jpg
            // 4: Isolate files as directories
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date()); // Date Directory: November 21, 2021
            // 5: Upload directory of final documents
            File targetFile = new File(uploadFolder + dir, datePath); // Final directory generated; D://tmp/avatar/2021/11/21
            // 6: If dirFile does not exist, it is created
            if (!targetFile.exists()) targetFile.mkdirs();
            // 7: Specify the full file name after the file is uploaded
            File dirFileName = new File(targetFile, newFileName); // The final path of the file on the server is D://tmp/avatar/2021/11/21/dfasf42432.jpg
            // 8: File upload
            multipartFile.transferTo(dirFileName);

            // 9: Accessible path http://localhost:8082/avatar/2021/11/21/dfasf42432.jpg
            String fileName = dir + "/" + datePath + "/" + newFileName;
            return rootPath +staticPatterPath+ fileName;
        } catch (IOException e) {
            e.printStackTrace();
            return "fail";
        }
    }
}

03. Obtain multiple information of the file

Just return to map

UploadService

package com.qd.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * File upload
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/21 21:20
 */
@Service
public class UploadService {

    // Root path
    @Value("${file.rootPath}")
    private String rootPath;
    // Mapping directory
    @Value("${file.uploadFolder}")
    private String uploadFolder;
    // Access path to the resource
    @Value("${file.staticPatterPath}")
    private String staticPatterPath;

    /**
     * MultipartFile Object is the class of file upload and receive provided by spring MVC
     * File upload underlying principle request. Getinputstream()
     *
     * @param multipartFile
     * @param dir
     * @return
     */
    public Map<String, Object> uploadImgMap(MultipartFile multipartFile, String dir) {

        try {
            // 1: Real file name
            String originalFilename = multipartFile.getOriginalFilename(); // Uploaded file aa.jpg
            // 2: Intercepted file name.jpg
            String imgSuffix = originalFilename.substring(originalFilename.lastIndexOf(".")); // Get. jpg
            // 3: Generate a unique file name
            String newFileName = UUID.randomUUID().toString() + imgSuffix;  // Randomly generated, such as dfasf42432.jpg
            // 4: Isolate files as directories
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date()); // Date Directory: November 21, 2021
            // 5: Upload directory of final documents
            File targetFile = new File(uploadFolder + dir, datePath); // Final directory generated; D://tmp/avatar/2021/11/21
            // 6: If dirFile does not exist, it is created
            if (!targetFile.exists()) targetFile.mkdirs();
            // 7: Specify the full file name after the file is uploaded
            File dirFileName = new File(targetFile, newFileName); // The final path of the file on the server is D://tmp/avatar/2021/11/21/dfasf42432.jpg
            // 8: File upload
            multipartFile.transferTo(dirFileName);

            // 9: Accessible path http://localhost:8082/avatar/2021/11/21/dfasf42432.jpg
            String fileName = dir + "/" + datePath + "/" + newFileName;
            Map<String, Object> map = new HashMap<>();
            map.put("url", rootPath + staticPatterPath + fileName); // url
            map.put("size", multipartFile.getSize());// size
            map.put("fileName", originalFilename);// Real file name
            map.put("ext", imgSuffix);// Suffix
            return map;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

UploadController

package com.qd.controller;

import com.qd.service.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Create by IntelliJ IDEA
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/21 21:01
 */
@Controller
public class UploadController {

    @Autowired
    private UploadService uploadService;

    @GetMapping("/upload")
    public String toUpload() {
        return "upload";
    }
    
    @PostMapping("/upload/file2")
    @ResponseBody
    public Map<String, Object> uploadMap(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {

        // 1: Null judgment
        if (multipartFile.isEmpty()) {
            return null;
        }

        // 2: Determine whether the document conforms to
        //String contentType = multipartFile.getContentType();// Get file type
        //if (!"image/png".equals(contentType) || !"image/jpg".equals(contentType)) {
        //    return "the file format does not match";
        //}

        // 3: Gets the folder specified by the user
        // Purpose: for isolation, different businesses and different files are put into different directories
        String dir = request.getParameter("dir");
        return uploadService.uploadImgMap(multipartFile, dir);
    }
}

front end

    <h2>File upload</h2>
    <form action="/upload/file2" id="uploadform" method="post" enctype="multipart/form-data">
        <input type="text" name="dir" value="avatar" hidden>
        <input type="file" name="file" accept="image/png,image/jpg" onchange="upload()">
        <!--<input type="submit" value="Click me to upload">-->
    </form>

    <script>
        function upload() {
            console.log("Select a picture to upload~")
            document.getElementById("uploadform").submit();
        }
    </script>

result

ok ~ so far, let's discuss the file upload of this machine. In the future, we will continue to learn about file upload using alicloud oss storage.

Tags: Java Spring Boot

Posted on Mon, 22 Nov 2021 00:37:55 -0500 by danoush