springboot 文件上传示例(webuploader插件) 2025979编辑
Heaven helps those who help themselves
资深码农+深耕理财=财富自由
欢迎关注
资深码农+深耕理财=财富自由
欢迎关注

springboot 文件上传示例(webuploader插件)
Created by Marydon on 2022-01-12 19:12
1.情景展示
文件上传,在开发过程中,经常会用到,springboot如何接收上传文件?
本文将以springboot为例,如何接收前端的文件请求;
上传文件使用插件更方便,这里我使用webuploader。
2.前端代码
第一步:准备webuploader插件放到项目当中;
由于,springboot在项目启动的时候,会自动将static目录下的静态资源(前端代码)加载到项目当中;
所以,我这里为了省事儿,就不创建web目录了;
而且springboot还会自动将resources/static目录下的index.html当做项目的欢迎页(我这里为了省事,就没有配置请求与页面想对照的映射关系)。
现在,我们来对前端代码进行整体认知;
一个要存放插件的位置:webuploader;
一个要展示插件的页面:index.html;
一个要处理文件上传的js:upload.js;
index.html需要引入:
webuploader.css和webuploader.js;
必须在webuploader.js引入之前引入jQuery.js(因为它依赖jQuery);
include.js包含的内容如下:
// 获取请求路径 var pathName = window.document.location.pathname; // 通过截取得到项目名称 var baseUrl = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
用途:获取该项目的名称。
html的核心代码为:
<div id="filePicker" style="line-height:15px;" class="webuploader-container"> <div class="webuploader-pick">选择文件</div> </div>
webuploader插件会通过init()方法,对filePicker这个div里面追加内容,例如:
js核心代码:
查看代码
/** * 该插件批量上传的本质: * 每个文件单独发送一个上传请求,所以,其本质还是单文件上传,而不是真正含义上的:一次请求包含多个文件。 */ this.init = function () { var state = 'pending'; var upUrl = baseUrl + '/file/upload.do'; var uploader = WebUploader.create({ auto: true, // 选择文件后自动上传,默认不自动上传需要触发 swf: baseUrl + '/webuploader/Uploader.swf', // swf文件路径 server: upUrl, // 上传文件的接口(替换成你们后端给的接口路径) // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: '#filePicker', accept: { //extensions: 'xls,xlsx', // 允许的文件后缀,不带点,多个用逗号分割,这里支持老版的Excel和新版的 mimeTypes: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // 说明:extensions没用,不生效 // 只有mimeTypes的值对应文件域的accept属性,仅能通过它来控制上传文件的类型 // 文件类型,也可以通过“.后缀名”的方式来实现,如:.xls,.xlsx }, resize: false, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! /* duplicate :true */ //可重复上传 }); /** * 文件被加入队列之前触发 * @explain 主要用来传其它参数 */ uploader.on('beforeFileQueued', function (file) { var obj = new Object(); obj.THEMEID = $('#THEMEID').val(); uploader.options.formData = obj; }); /** * 上传成功 */ uploader.on('uploadSuccess', function( file, result) { alert(JSON.stringify(result)); }); /** * 上传失败 */ uploader.on('uploadError', function( file, result) { // alert('文件上传失败!'); alert(JSON.stringify(result)); }); /** * 上传完成 */ uploader.on( 'uploadComplete', function( file ) { }); uploader.on( 'all', function( type ) { if ( type === 'startUpload' ) { state = 'uploading'; } else if ( type === 'stopUpload' ) { state = 'paused'; } else if ( type === 'uploadFinished' ) { state = 'done'; } }); }
HTML完整代码:
查看代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文件上传</title> <link rel="stylesheet" type="text/css" href="webuploader/webuploader.css"> <script type="text/javascript" src="common/js/jquery-3.6.0.min.js"></script> <script type="text/javascript" src="webuploader/webuploader.js"></script> <script type="text/javascript" src="common/js/include.js"></script> <script type="text/javascript" src="upload.js"></script> </head> <body> <h1>欢迎来到Marydon的博客园</h1> <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 90%"> <tr> <td style="text-align: center"> <div id="filePicker" style="line-height:15px;" class="webuploader-container"> <div class="webuploader-pick">选择文件</div> </div> </td> <td> <span style="color: #898989">备注:扫描文件格式为xls</span> </td> </tr> </table> </body> </html>
注意:关键点在于,引入文件的路径问题,不要搞错了。
JAVASCRIPT完整代码:
查看代码
var upload = new Upload(); window.onload = function(){ // 不要忘了调用WebUploader的初始化函数 upload.init(); } function Upload() { var object = this; /** * 该插件批量上传的本质: * 每个文件单独发送一个上传请求,所以,其本质还是单文件上传,而不是真正含义上的:一次请求包含多个文件。 */ this.init = function () { var uploadUrl = baseUrl + '/file/upload.do'; var uploader = WebUploader.create({ auto: true, // 选择文件后自动上传,默认不自动上传需要触发 swf: baseUrl + '/webuploader/Uploader.swf', // swf文件路径 server: uploadUrl, // 上传文件的接口(替换成你们后端给的接口路径) // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: '#filePicker', accept: { //extensions: 'xls,xlsx', // 允许的文件后缀,不带点,多个用逗号分割,这里支持老版的Excel和新版的 mimeTypes: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // 说明:extensions没用,不生效 // 只有mimeTypes的值对应文件域的accept属性,仅能通过它来控制上传文件的类型 // 文件类型,也可以通过“.后缀名”的方式来实现,如:.xls,.xlsx }, resize: false, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! /* duplicate :true */ //可重复上传 }); /** * 文件被加入队列之前触发 * @description 主要用来传其它参数 * @explain 我没有在这里演示,没有传其它参数 */ uploader.on('beforeFileQueued', function (file) { var obj = new Object(); obj.THEMEID = $('#THEMEID').val(); uploader.options.formData = obj; }); /** * 上传成功 */ uploader.on('uploadSuccess', function( file, result) { alert(JSON.stringify(result)); }); /** * 上传失败 */ uploader.on('uploadError', function( file, result) { // alert('文件上传失败!'); alert(JSON.stringify(result)); }); }; }
注意:关键点在于,需要对插件WebUploader进行初始化。
3.后端代码
难点在于:如何接收前端发过来的请求?
其实,很简单:参数file的值就是MultipartFile类型的文件。
文件上传,上传的参数至少会有以下6个参数:
为了方便对于参数的使用,我用实体类来接收这些参数,这样,在后续用到的时候就会很方便。
查看代码
import lombok.Getter; import lombok.Setter; import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; /** * 文件上传请求参数 * @description: * @author: Marydon * @date: 2022-01-10 15:38 * @version: 1.0 * @email: marydon20170307@163.com */ @Getter @Setter public class UploadParamsDto { @NotBlank(message = "id:不能为空") private String id; @NotBlank(message = "name:不能为空") private String name; @NotBlank(message = "type:不能为空") private String type; @NotBlank(message = "lastModifiedDate:不能为空") private String lastModifiedDate; @NotBlank(message = "size:不能为空") private String size; @NotNull(message = "file:不能为空") private MultipartFile file; }
如果不需要对参数进行非空校验,删掉这些属性对应的注解即可。
JAVA控制层完成代码:
查看代码
import com.example.upload.web.dto.UploadParamsDto; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * 文件上传控制层 * @description: * @author: Marydon * @date: 2022-01-10 10:16 * @version: 1.0 * @email: marydon20170307@163.com */ @Slf4j @RestController @RequestMapping("/file") public class UploadController { // 文件存放路径:项目路径/files private static final String UPLOADED_FOLDER = System.getProperty("user.dir") + File.separator + "files"; /* * 文件上传 * @attention: 不支持批量上传 * @description: 请求类型-multipart/form-data * @date: 2022/1/11 10:23 * @param: paramsDto * @return: java.util.Map */ @PostMapping("/upload.do") public Map<String, Object> upload(@Validated UploadParamsDto paramsDto) { // 即将返回的数据 Map<String, Object> resultMap = new HashMap<>(2); resultMap.put("isSuccess", true); resultMap.put("error", ""); Map<String, String> errorMap = new HashMap<>(); // 获取上传的文件 MultipartFile file = paramsDto.getFile(); // 新文件的文件名 String fileName = System.currentTimeMillis() + "_" + paramsDto.getName(); // 新文件的生成 File copyFile = new File(UPLOADED_FOLDER + File.separator + fileName); // 目录不存在就自动创建 copyFile.mkdirs(); try { // 将multipartfile文件转移到file对象所代表的文件中 // 该方法可以将文件夹直接变为文件 // 当copyFile代表的是一个目录时,正常情况文件是无法输入的,而transferTo()方法会将该目录直接变为文件并输入数据 file.transferTo(copyFile); } catch (IOException e) { e.printStackTrace(); log.error(e.getMessage()); // 如果报错,意味着该文件上传失败,将原文件名和报错信息返回 errorMap.put(paramsDto.getName(), e.getMessage()); } if (!errorMap.isEmpty()) { resultMap.put("error", errorMap); } return resultMap; } }
难点还有:如何获取保存文件的目录;
新文件名的命名规则;
文件的快速复制。
当然,如果只是根据上传的文件进行解析处理,而不保存的话,不会遇到以上3个问题。
说明:
请求格式:multipart/form-data;
返回格式:application/json。
另外,如果,需要对实体类UploadParamsDto进行参数校验,除了需要在它前面加注解@Validated外,还要引入对应的注解jar依赖。
<!--spring对参数进行校验:hibernate validator--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.18.Final</version> </dependency>
更多细节,我在之前的文章讲过。
4.效果展示
直接来到欢迎页
点击“选择文件”,选择要上传的文件,支持多选。
最终上传的文件存放位置
5.扩展
通过配置文件限制上传文件大小
如果,对上传文件的大小有限制的话,可以通过配置来实现。
查看代码
####spring配置#### ####开发环境数据源配置 spring: ###文件上传大小限制 servlet: multipart: #是否支持批量上传(默认值 true) enabled: true #上传文件最大为 1M(默认值 1M) max-file-size: 10MB #上传请求最大为 10M(默认值 10M) max-request-size: 10MB #文件大小阈值,当大于这个阈值时将写入到磁盘,否则存在内存中(默认值0,即:直接将文件写入磁盘) file-size-threshold: 0 #判断是否要延迟解析文件(默认值false) resolve-lazily: false #存放上传文件的临时目录 location:
禁止多选
WebUploader插件,默认支持多文件上传;
如果我们需要限制每次只允许上传一个文件的话,可以通过如下配置进行禁止。
pick对象里面声明multiple属性,并将值设为false。
pick: { 'id': '#filePicker',//文件上传按钮所在位置(通过ID来指定) 'multiple': false //禁止多选 },
页面初始化后,文本域没有multiple属性。
下面这种方式,会默认允许多选。
说明:
文件域的multiple属性,可以控制文件的单选和多选;
支持多选:声明multiple属性;
禁止多选:不声明multiple属性。
<input type="file" multiple="multiple">
文件域的accept属性,可以控制上传文件的文件类型。
方式一:
<input type="file" accept="文件对应的文件类型(mimetype),如:application/pdf">
方式二:推荐使用
<input type="file" accept="文件对应的文件后缀名(.文件名),如:.sql">
2023年3月27日15:31:48
上传jpg文件
当使用该插件上传jpg格式图片时,可能会上传失败,报错信息如下:
需要声明compress属性,如果不需要压缩的话,将值设为false即可。
var uploader = WebUploader.create({ auto: true, swf: baseUrl + '/commons/js/ueditor/third-party/webuploader/Uploader.swf', server: upUrl, pick: '#filePicker', method: 'POST', resize: false, compress: false,// 不声明将导致部分jpg文件无法上传 accept: { title: 'Images', extensions: 'gif,jpg,jpeg,bmp,png,pdf', mimeTypes: 'image/*,application/pdf' } });
写在最后
哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!
相关推荐:
与君共勉:最实用的自律是攒钱,最养眼的自律是健身,最健康的自律是早睡,最改变气质的自律是看书,最好的自律是经济独立 。
您的一个点赞,一句留言,一次打赏,就是博主创作的动力源泉!
↓↓↓↓↓↓写的不错,对你有帮助?赏博主一口饭吧↓↓↓↓↓↓
本文来自博客园,作者:Marydon,转载请注明原文链接:https://www.cnblogs.com/Marydon20170307/p/15794176.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南