SpringBoot 2.x (3):文件上传
文件上传有两个要点
一是如何高效地上传:使用multipartfile替代fileoutputsteam
二是上传文件的路径问题的解决:使用路径映射
文件路径通常不在classpath,而是本地的一个固定路径或者是一个文件服务器路径
springboot的路径:
src/main/java:存放代码
src/main/resources:存放资源
static: 存放静态文件:css、js、image (访问方式 http://localhost:8080/js/main.js)
templates:存放静态页面:html,jsp
application.properties:配置文件
但是要注意:
比如我在static下新建index.html,那么就可以访问localhost:8080/index.html看到页面
如果在templates下新建index.html,那么访问会显示错误,除非在controller中进行跳转
如果想对默认静态资源路径进行修改,则在application.properties中配置:
spring.resources.static-locations = classpath:/meta-inf/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
这里默认的顺序是先从/meta-inf/resources中进行寻找,最后找到/public,可以在后边自行添加
文件上传不是老问题,这里就当是巩固学习了
方式:multipartfile file,源自springmvc
首先需要一个文件上传的页面
在static目录下新建一个html页面:
<!doctype html> <html> <head> <title>文件上传</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> </head> <body> <form enctype="multipart/form-data" method="post" action="/upload"> 文件:<input type="file" name="head_img" /> 姓名:<input type="text" name="name" /> <input type="submit" value="上传" /> </form> </body> </html>
文件上传成功否需要返回的应该是一个封装的对象:
package org.dreamtech.springboot.domain; import java.io.serializable; public class filedata implements serializable { private static final long serialversionuid = 8573440386723294606l; // 返回状态码:0失败、1成功 private int code; // 返回数据 private object data; // 错误信息 private string errmsg; public int getcode() { return code; } public void setcode(int code) { this.code = code; } public object getdata() { return data; } public void setdata(object data) { this.data = data; } public string geterrmsg() { return errmsg; } public void seterrmsg(string errmsg) { this.errmsg = errmsg; } public filedata(int code, object data) { super(); this.code = code; this.data = data; } public filedata(int code, object data, string errmsg) { super(); this.code = code; this.data = data; this.errmsg = errmsg; } }
处理文件上传的controller:
package org.dreamtech.springboot.controller; import java.io.file; import java.util.uuid; import javax.servlet.http.httpservletrequest; import org.dreamtech.springboot.domain.filedata; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.requestparam; import org.springframework.web.bind.annotation.restcontroller; import org.springframework.web.multipart.multipartfile; @restcontroller public class filecontroller { private static final string file_path = "d:\\temp\\images\\"; static { file file = new file(file_path); if (!file.exists()) { file.mkdirs(); } } @requestmapping("/upload") private filedata upload(@requestparam("head_img") multipartfile file, httpservletrequest request) { if (file.isempty()) { return new filedata(0, null, "文件不能为空"); } string name = request.getparameter("name"); system.out.println("用户名:" + name); string filename = file.getoriginalfilename(); system.out.println("文件名:" + filename); string suffixname = filename.substring(filename.lastindexof(".")); system.out.println("后缀名:" + suffixname); filename = uuid.randomuuid() + suffixname; string path = file_path + filename; file dest = new file(path); system.out.println("文件路径:" + path); try { // transferto文件保存方法效率很高 file.transferto(dest); system.out.println("文件上传成功"); return new filedata(1, filename); } catch (exception e) { e.printstacktrace(); return new filedata(0, filename, e.tostring()); } } }
还有问题要处理,保存图片的路径不是项目路径,而是本地的一个固定路径,那么要如何通过url访问到图片呢?
对路径进行映射:比如我图片保存在d:\temp\image,那么我们希望访问localhost:8080/image/xxx.png得到图片
可以修改tomcat的配置文件,也可以按照下面的配置:
package org.dreamtech.springboot.config; import org.springframework.context.annotation.configuration; import org.springframework.web.servlet.config.annotation.resourcehandlerregistry; import org.springframework.web.servlet.config.annotation.webmvcconfigurer; @configuration public class mywebappconfigurer implements webmvcconfigurer { @override public void addresourcehandlers(resourcehandlerregistry registry) { registry.addresourcehandler("/image/**").addresourcelocations("file:d:/temp/images/"); } }
还有一些细节问题不得忽略:对文件大小进行限制
package org.dreamtech.springboot.config; import javax.servlet.multipartconfigelement; import org.springframework.boot.web.servlet.multipartconfigfactory; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.util.unit.datasize; @configuration public class filesizeconfigurer { @bean public multipartconfigelement multipartconfigelement() { multipartconfigfactory factory = new multipartconfigfactory(); // 单个文件最大10mb factory.setmaxfilesize(datasize.ofmegabytes(10l)); /// 设置总上传数据总大小10gb factory.setmaxrequestsize(datasize.ofgigabytes(10l)); return factory.createmultipartconfig(); } }
打包后的项目如何处理文件上传呢?
顺便记录springboot打包的坑,mvn clean package运行没有问题,但是不太方便
于是eclipse中run as maven install,但是会报错,根本原因是没有配置jdk,配置的是jre:
解决:https://blog.csdn.net/lslk9898/article/details/73836745
图片量不大的时候,我们可以用自己的服务器自行处理,
如果图片量很多,可以采用图片服务器,自己用nginx搭建或者阿里oss等等
推荐阅读
-
SpringBoot实现文件上传下载功能小结
-
解决springboot MultipartFile文件上传遇到的问题
-
SpringBoot通过Minio实现大文件分片上传
-
基于SpringBoot上传任意文件功能的实现
-
servlet3文件上传操作
-
java web中的servlet3 upload上传文件实践
-
*php上传出现异常,代号为3,表示是文件只有部分被上传
-
解决springboot上传文件报错:The field XXX exceeds its maximum permitted size of 1048576 bytes
-
三款php多文件上传实例代码(1/3)
-
投票系统 不用数据库的多用户文件*上传投票系统3