SpringBoot(八)SpringBoot中文件上传案例

本文以 SpringBoot 实现一个 文件上传的简单操作,可实现控制文件上传大小,文件上传路径。

1、准备工作

创建一个SpringBoot项目,创建SpringBoot 项目同时添加 webapp 文件夹 用于放 html 页面。

项目结构:

SpringBoot(八)SpringBoot中文件上传案例_第1张图片

可能你创建的SpringBoot项目没有webapp文件夹,我也为你准备了解决办法。

SpringBoot(八)SpringBoot中文件上传案例_第2张图片


解决方法:

点击工具栏 Project Structure 按钮[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q3L0GiXU-1598349113955)(C:\Users\hainei-developer\Desktop\微信截图_20200825164438.png)],在打开的窗口中选中 Moudles -> Web,按照步骤添加配置:

SpringBoot(八)SpringBoot中文件上传案例_第3张图片

项目有webapps文件夹了吧,继续来看文件上传吧!↓


2、添加依赖

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-configuration-processorartifactId>
    <optional>trueoptional>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-thymeleafartifactId>
dependency>

完整pom.xml,在build中添加resource保证在webapps下面的html文件进行编译。


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.3.RELEASEversion>
        <relativePath/> 
    parent>
    <groupId>com.ifknowgroupId>
    <artifactId>spring-boot-fileuploadartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>spring-boot-fileuploadname>
    <description>Demo project for Spring Bootdescription>

    <properties>
        <java.version>1.8java.version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-configuration-processorartifactId>
            <optional>trueoptional>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>


        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.12version>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
        <resources>
            <resource>
                <directory>src/main/webappdirectory>
                
                <targetPath>META-INF/resourcestargetPath>
                <includes>
                    <include>**/**include>
                includes>
            resource>
            <resource>
                <directory>src/main/resourcesdirectory>
                <filtering>truefiltering>
                <includes>
                    <include>**/*include>
                includes>
            resource>
        resources>
    build>

project>

3、配置application.yml文件

配置项目上传路径和文件上传大小。

server:
  port: 8081
# 文件上传路径配置
my:
  uploadFile:
    uploadPath: C:\softInstall\Tomcat 8.5\webapps\fileupload\
    readPath: \fileupload\
# 文件上传大小
spring:
  servlet:
    multipart:
      enabled: true
      file-size-threshold: 0
      max-file-size: 200MB
      max-request-size: 200MB

4、编写一个html页面

编写一个HTML页面,页面上一个file的button,为了展现技术,很无聊的加了一个简陋的进度条。


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传title>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js">script>
head>
<style>
    .box {
        height: 30px;
        width: 200px;
        border: 1px solid green;
        margin-top: 30px;
    }

    article {
        height: 100%;
        width: 0;
        background: palegreen;
    }
style>
<body>
<input type="file" id="file">
<div class="box">
    <article class="cont">article>
div>
<a id="back" href="#">##a>
body>
<script>
    function uploadImg(fileInfo) {
        const data = new FormData();
        data.append('file', fileInfo)
        return new Promise((reslove, reject) => {
            $.ajax({
                type: 'post',
                url: '/file/upload',
                data,
                processData: false,
                contentType: false,
                xhr() {
                    const myXhr = $.ajaxSettings.xhr();
                    myXhr.upload.addEventListener('progress', (e) => {
                        console.log(e.loaded, e.total)
                        document.querySelector('.cont').style.width = `${(e.loaded / e.total) * 100}%`
                    })
                    return myXhr
                },
                success(data) {
                    console.log(data.url)
                    $("#back").attr("href", "http://localhost:8080" + data.url)
                    $("#back").text(data.newName)
                },
                error() {
                }
            })
        })
    }

    const file = document.querySelector('#file');
    file.onchange = function (e) {
        document.querySelector('.cont').style.width = '0px'
        const files = e.target.files;
        [...files].forEach((res) => {
            uploadImg(res).then((res) => {
            }, (err) => {
            })
        })
    }
script>
html>

5、后台实现

  • 读取application.yml的配置文件中定义的内容,编写一个配置类
package com.ifknow.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: ifknow 
* @Date: 2020/8/25 10:18
* @Description: 读取配置文件中定义的文件上传路径 */
@Configuration @ConfigurationProperties(prefix = "my", ignoreUnknownFields = false) public class ObtainProperties { /** * 文件上传配置 */ private final UploadFile uploadFile = new UploadFile(); public UploadFile getUploadFile() { return uploadFile; } @Data public static class UploadFile { private String uploadPath; private String readPath; } }
  • 文件上传实现
package com.ifknow.utils;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Author: ifknow 
* @Date: 2020/8/25 10:28
* @Description: NO Description */
public class FileUtil { /** * 上传文件接口 * * @param file 文件 * @param request * @param model * @return */ public Map<String, Object> upload(MultipartFile file, HttpServletRequest request, FileModel model) { //文件不为空 if (!file.isEmpty()) { //上传文件名 String fileName = file.getOriginalFilename(); String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); try { Map<String, Object> map = this.toUpload(file, suffix, fileName, request, model); return map; } catch (Exception e) { e.printStackTrace(); } } return null; } /** * 上传操作 * * @param file 文件 * @param suffix 后缀 * @param fileName 文件名 * @param request * @param model * @return */ public Map<String, Object> toUpload(MultipartFile file, String suffix, String fileName, HttpServletRequest request,FileModel model) { suffix = suffix.toLowerCase(); Map<String, Object> pathMap = this.filePath(suffix, model); String filePath = pathMap.get("filePath").toString(); File realPath = new File(filePath, fileName); if (!realPath.getParentFile().exists()) { realPath.getParentFile().mkdirs(); } String newName = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf(".")); File newFile = new File(filePath + File.separator + newName); try { file.transferTo(newFile); } catch (Exception e) { e.printStackTrace(); } String fileType = pathMap.get("fileType").toString(); Map<String, Object> map = new HashMap<String, Object>(); //后缀 map.put("suffix", suffix); //原文件名 map.put("oldName", fileName.substring(0, fileName.lastIndexOf("."))); //新文件名 map.put("newName", newName.substring(0, newName.lastIndexOf("."))); //文件大小 map.put("fileSize", file.getSize()); //路径 map.put("url", model.getReadPath() + fileType + File.separator + newName); // 类型(0视/1文/2图片) map.put("type", getTypeByUrl(suffix)); return map; } /** * 判断文件的类型:图片、视频、word。。。返回路径 * * @param suffix 后缀名 * @return */ public Map<String, Object> filePath(String suffix, FileModel model) { Map<String, Object> map = new HashMap<String, Object>(); String filePath = ""; String fileType = ""; if (suffix.equals("jpg") || suffix.equals("png")) { fileType = "images"; } else if (suffix.equals("mov")) { fileType = "mov"; } else if (suffix.equals("mp4")) { fileType = "mp4"; } else if (suffix.equals("xlsx") || suffix.equals("xls")) { fileType = "excel"; } else if (suffix.equals("pdf")) { fileType = "pdf"; } else if (suffix.equals("ppt") || suffix.equals("pptx")) { fileType = "ppt"; } else if (suffix.equals("doc") || suffix.equals("docx")) { fileType = "word"; } else { fileType = "other"; } filePath = model.getUploadPath() + fileType; map.put("filePath", filePath); map.put("fileType", fileType); return map; } public int getTypeByUrl(String suffix) { suffix = suffix.toLowerCase().trim(); if (!"jpg".equals(suffix) && !"png".equals(suffix)) { if ("mov".equals(suffix) || "mp4".equals(suffix)) { return 0; } else { return 1; } } return 2; } }
package com.ifknow.utils;

/**
 * @Author: ifknow 
* @Date: 2020/8/25 10:00
* @Description: NO Description */
public class FileModel { private String uploadPath; private String readPath; public String getUploadPath() { return uploadPath; } public FileModel setUploadPath(String uploadPath) { this.uploadPath = uploadPath; return this; } public String getReadPath() { return readPath; } public FileModel setReadPath(String readPath) { this.readPath = readPath; return this; } }
  • 编写controller测试
package com.ifknow.controller;

import com.ifknow.config.ObtainProperties;
import com.ifknow.utils.FileModel;
import com.ifknow.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @Author: ifknow 
* @Date: 2020/8/25 9:59
* @Description: NO Description */
@Slf4j @CrossOrigin @RestController @RequestMapping("/file") public class FileUploadController { @Autowired private ObtainProperties obtainProperties; @PostMapping("/upload") public Map<String, Object> upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) { FileModel model = new FileModel().setUploadPath(obtainProperties.getUploadFile().getUploadPath()).setReadPath(obtainProperties.getUploadFile().getReadPath()); FileUtil uploadUtil = new FileUtil(); Map<String, Object> map = uploadUtil.upload(file, request, model); log.info(file.getOriginalFilename() + " 上传成功"); return map; } }

6、接口调试

打开浏览器访问 http://localhost:8081/index.html

SpringBoot(八)SpringBoot中文件上传案例_第4张图片

选择文件后,可看到效果,接口返回的文件信息,在实际的开发中可用于图片回显等业务需求。

SpringBoot(八)SpringBoot中文件上传案例_第5张图片

本文中暂未考虑到异常处理,可以自己了解。方案:可以使用@RestControllerAdcvice。


示例代码-GitHub

示例代码-Gitee

个人博客-ifknow

你可能感兴趣的:(Spring,Boot,spring,boot)