《穿越SpringBoot 》 第四章-SpringBoot IO流 | 第1节- SpringBoot 中的文件上传

前题

基于:IntelliJ IDEAMaven构建工具JDK1.8SpringBoot 2.3.4编写。

官人如需使用 Maven 请阅读教程:Maven 构建工具的下载与安装

官人如需使用 IDEA 请阅读教程:IntelliJ IDEA

更多干货

请阅读:《穿越SpringBoot》系列文章

请参考:Java学习资料

定义

文件上传和下载是JAVA WEB中常见的一种操作,文件上传主要是将文件通过IO流传输到服务器的某一个特定的文件夹下;

使用

pom.xml 依赖

在pom.xml中添加上spring-boot-starter-webspring-boot-starter-thymeleaf的依赖

<?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.3.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>io</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>io</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>
<!--thymeleaf模板引擎-->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
<!--web-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
<!--test-->
		<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>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

application.properties配置文件

默认情况下Spring Boot无需做任何配置也能实现文件上传的功能

# 关闭 thymeleaf 缓存
spring.thymeleaf.cache=false
# 是否支持批量上传   (默认值 true)
spring.servlet.multipart.enabled=true
# 上传文件的临时目录 (一般情况下不用特意修改)
spring.servlet.multipart.location=
# 上传文件最大为 1M (默认值 1M 根据自身业务自行控制即可)
spring.servlet.multipart.max-file-size=1048576
# 上传请求最大为 10M(默认值10M 根据自身业务自行控制即可)
spring.servlet.multipart.max-request-size=10485760
# 文件大小阈值,当大于这个阈值时将写入到磁盘,否则存在内存中,(默认值0 一般情况下不用特意修改)
spring.servlet.multipart.file-size-threshold=0
# 判断是否要延迟解析文件(相当于懒加载,一般情况下不用特意修改)
spring.servlet.multipart.resolve-lazily=false

编写controller层

实现 单文件上传多文件上传BASE64编码三种上传方式。

@RequestParam("file")此处的"file"对应的就是html 中 name="file" 的 input 标签.

而将文件真正写入的还是借助的commons-io中的FileUtils.copyInputStreamToFile(inputStream,file)

单文件上传: 访问/uploads/upload1/uploads/upload4具体可结合index.html

多文件上传访问:/uploads/upload2

BASE64编码上传访问:/uploads/upload3

都可在控制台查看日志输出。

package com.example.io.controller;

import org.apache.catalina.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;

@Controller
@RequestMapping("/uploads")
public class FilesUploadController {
    
    
    private static final Logger log = LoggerFactory.getLogger(FilesUploadController.class);


    //跳转到 index页面
    @GetMapping
    public  String index(){
    
    
        return "index";
    }

    @PostMapping("/upload1")
    @ResponseBody
    public Map<String,String> upload1(@RequestParam("file") MultipartFile file) throws IOException {
    
    

        //控制台输出日志
        log.info("[文件类型] - [{}]", file.getContentType());
        log.info("[文件名称] - [{}]", file.getOriginalFilename());
        log.info("[文件大小] - [{}]", file.getSize());

        file.transferTo(new File("F:\\源码\\文件上传\\upload\\"+file.getOriginalFilename()));

        Map<String,String> result=new HashMap<>();

        result.put("contentType",file.getContentType());
        result.put("filename",file.getOriginalFilename());
        result.put("fileSize",file.getSize()+"");
        return result;
    }


    //文件上传相关代码
    @RequestMapping("/upload4")
    @ResponseBody
    public String upload(@RequestParam("test") MultipartFile file) {
    
    
        if (file.isEmpty()) {
    
    
            return "文件为空";
        }
        // 获取文件名
        String fileName = file.getOriginalFilename();
        log.info("上传的文件名为:" + fileName);
        // 获取文件的后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        log.info("上传的后缀名为:" + suffixName);
        // 文件上传后的路径
        String filePath = "F:\\源码\\文件上传\\upload\\u1\\";
        // 解决中文问题,linux下中文路径,图片显示问题
        // fileName = UUID.randomUUID() + suffixName;
        File dest = new File(filePath + fileName);
        // 检测是否存在目录
        if (!dest.getParentFile().exists()) {
    
    
            dest.getParentFile().mkdirs();
        }
        try {
    
    
            file.transferTo(dest);
            return "上传成功";
        } catch (IllegalStateException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return "上传失败";
    }

    @PostMapping("/upload2")
    @ResponseBody
    public List<Map<String, String>> upload2(@RequestParam("file") MultipartFile[] files) throws IOException {
    
    
        if (files == null || files.length == 0) {
    
    
            return null;
        }
        List<Map<String, String>> results = new ArrayList<>();
        for (MultipartFile file : files) {
    
    
            // TODO Spring Mvc 提供的写入方式
            //file.getOriginalFilename 原始文件名
            file.transferTo(new File("F:\\源码\\文件上传\\uploads\\" + file.getOriginalFilename()));
            Map<String, String> map = new HashMap<>(16);
            map.put("contentType", file.getContentType());
            map.put("fileName", file.getOriginalFilename());
            map.put("fileSize", file.getSize() + "");
            results.add(map);
        }
        return results;
    }
   
    @PostMapping("/upload3")
    @ResponseBody
    public void upload2(String base64) throws IOException {
    
    
        // TODO BASE64 方式的 格式和名字需要自己控制(如 png 图片编码后前缀就会是 data:image/png;base64,)
        final File tempFile = new File("F:\\源码\\文件上传\\upload\\test.jpg");
        // TODO 防止有的传了 data:image/png;base64, 有的没传的情况
        String[] d = base64.split("base64,");
        final byte[] bytes = Base64Utils.decodeFromString(d.length > 1 ? d[1] : d[0]);
        FileCopyUtils.copy(bytes, tempFile);
    }
}

编写index.html

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<link rel="stylesheet" href="style.css">
<body>

<h2>单文件上传:</h2>
<div>
    <form method="POST" enctype="multipart/form-data" action="/uploads/upload1">
        <p>
            文件1:<input type="file" name="file"/>
            <input type="submit" value="上传"/>
        </p>
    </form>
</div>


<form action="/uploads/upload4" method="POST" enctype="multipart/form-data">
    文件:<input type="file" name="test"/>
    <input type="submit" />
</form>
<hr/>

<h2>多文件上传:</h2>

<div>
    <form method="POST" enctype="multipart/form-data"
          action="/uploads/upload2">
        <p>
            文件1:<input type="file" name="file"/>
        </p>
        <p>
            文件2:<input type="file" name="file"/>
        </p>
        <p>
            <input type="submit" value="上传"/>
        </p>
    </form>
</div>

<hr/>
<h2>Base64文件上传:</h2>
<div>
    <form method="POST" action="/uploads/upload3">
        <p>
            BASE64编码:<textarea name="base64" rows="10" cols="80"></textarea>
            <input type="submit" value="上传"/>
        </p>
    </form>
</div>
</body>
</html>

测试

点击启动类后访问http://localhost:8080/

在这里插入图片描述
单文件和多文件上传就不演示了下面是Base64文件上传的方式:

打开浏览器访问:http://base64.xpcha.com/pic.html

选择一张图片将其转换为base64编码的,随后将转换后的base64字符串内容复制到下图中的文本框中,点击上传即可,随后到指定目录下就可以看到我们上传的文件了

在这里插入图片描述

总结

待完善…

本教程基于最新的spring-boot-starter-parent:2.3.4RELEASE编写,目前很多大佬都写过关于SpringBoot的教程了,如有雷同,请多多包涵.

猜你喜欢

转载自blog.csdn.net/weixin_47371330/article/details/109154614