8、SpringMVC-文件上传

一、导包相关包

<!-- 文件上传核心包 -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>${fileupload.version}</version>
</dependency>
<!-- 工具包 -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>${commons-lang.version}</version>
</dependency>

二、栗子

控制层

@RestController
public class UploaderController {
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String uploadSingleFile(@RequestParam("img") MultipartFile multipartFile) throws IOException {
        String imagePath = UploadUtils.saveImage(multipartFile);
        return imagePath;
    }

    @RequestMapping(value = "/uploads", method = RequestMethod.POST)
    public List<String> uploadMultipartFile(@RequestParam("img") MultipartFile[] multipartFiles) throws IOException {
        List<String> imgList = new ArrayList<>();
        for (MultipartFile multipartFile : multipartFiles) {
            String imagePath = UploadUtils.saveImage(multipartFile);
            imgList.add(imagePath);
        }
        return imgList;
    }
}

上传工具类

public class UploadUtils {
    public static final String SAVE_IMG_FILE = "images";

    public static String saveImage(MultipartFile multipartFile) throws IOException {
        // 通过配置文件获取保存的路径  注意上线的时候要修改成服务器保存的绝对路径
        ResourceBundle bundle = ResourceBundle.getBundle("sys");
        //获取到了跟路径
        String rootPath = bundle.getString("root.upload.path");
        // 获取保存图片名字的统一前缀
        String imgSuffix = bundle.getString("img.suffix");
        // 生成图片保存路径 根据日期保存
        String imagePath = String.format("%s%s%s", SAVE_IMG_FILE, File.separator, DateFormatUtils.format(new Date(), "yyyyMMdd"));
        /**
         * 保存到服务器数据库的路径
         */
        String savePath = String.format("%s%s%s", imagePath, File.separator, getFileName(imgSuffix, multipartFile.getOriginalFilename()));
        // 拼接保存的路径
        //     根路劲  +  业务需求的路径 +  文件名
        File imgFile = new File(String.format("%s%s%s",rootPath , File.separator , savePath));
        // 创建保存图片的文件
        FileUtils.touch(imgFile);
        // 将客服端图片写到文件中
        FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), imgFile);
        return savePath;
    }
    /**
     * 获取
     * @param oldName
     * @return
     */
    public static String getFileName(String suffixName, String oldName) {
        // 对图片进行重命名
        String prefix = suffixName + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        String suffix = oldName.substring(oldName.indexOf("."));
        return prefix + suffix;
    }
}

配置文件

sys.properties

# 文件大小最大值 单位kb 50M
maxUploadSize=52428800
# 单个文件限制大小 5m
maxUploadSizePerFile=5242880
# 设置文件编码
defaultEncoding = UTF-8
# 文件上传相关路径 
# 主路径  修改成你自己的
root.upload.path=/Users/xxx/xxx/upload
img.suffix = IMG_
file_suffix = FILE_

mvc配置文件

<!--注意id的值是固定的 -->  
<bean id="multipartResolver"
    <!-- 默认编码 -->
    <property name="defaultEncoding" value="${defaultEncoding}" />
    <!-- 文件大小最大值 -->
    <property name="maxUploadSize" value="${maxUploadSize}" />
    <!--    单个文件限制大小 -->
    <property name="maxUploadSizePerFile" value="${maxUploadSizePerFile}"/>
    <!-- 内存中缓存的最大值 -->
    <property name="maxInMemorySize" value="${maxInMemorySize}" />
    <property name="resolveLazily" value="${resolveLazily}"/>
</bean>

前端

  • 为了能上传文件,必须将表单的method设置为POST或者PUT
  • 并将enctype设置为multipart/form-data

普通表单

<h2>单文件上传</h2>
<form id='uploadForm' method="post" enctype="multipart/form-data">
    <input type="file" name="img">
    <button id='upload'>上传</button>
</form>
<h2>多文件上传</h2>
<form method="post" enctype="multipart/form-data">
    <input type="file" name="imgs" multiple>
  <button id='upload'>上传</button>
</form>

ajax

$('#upload').click(function () {
   let formData = new FormData($('#uploadForm')[0]); 
    $.ajax({
        url:'http://localhost:8080/upload/',
        dataType:'json',
        type:'POST',
        data: formData,
         // 使数据不做处理
        processData : false,
        // 不要设置Content-Type请求头
        contentType : false, 
        success: function(data){
            if (data.status == 'ok') {
                alert('上传成功!');
            }
        },
        error:function(response){
            console.log(response);
        }
    });
})

工程结构

三、核心类介绍

MultipartFile

方法说明
InputStream getInputStream()获取文件流
getOriginalFilename()获取上传文件的原名
boolean isEmpty()判断文件是否为空
void transferTo(File dest)保存文件到指定的文件中,注意父路径一定要存在
String getContentType()获取文件MIME类型

CommonsMultipartResolver

属性说明
uploadTempDir设置上传文件时的临时目录,默认是Servlet容器的临时目录。
maxUploadSize设置允许上传的总的最大文件大小,以字节为单位计算。当设为-1时表示无限制,默认是-1
maxUploadSizePerFilemaxUploadSizePerFile是限制每个上传文件的大小
maxInMemorySize设置在文件上传时允许写到内存中的最大值,以字节为单位计算,默认是10240
resolveLazily为true时,启用推迟文件解析,以便在UploadAction中捕获文件大小异常。
defaultEncoding表示用来解析request请求的默认编码格式,当没有指定的时候根据有些时候Servlet规范会使用默认值ISO-8859-1。当request自己指明了它的编码格式的时候就会忽略这里指定的

四、总结

前端

  • 请求方式一定要是post请求或者put请求
  • 请求的conentType必须是 multipart/form-data

文件

  • 对图片进行重命名,一般根据时间戳或者uuid生成规则,避免文件覆盖的现象
  • 保存的路径也根据实际的业务场景来动态生成

多文件上传

  • 使用MultipartFile[]数组来接受,使用集合来接受保存的路径
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值