前端:
FormDate:
FormDate一个WebAPI接口,是用来将表单数据组合成key/value的键值对形式的工具
<input type="file" id="fileInput" onchange="uploadFile()" multiple>
<input type="text" name="name">
<script>
function uploadFile() {
//js文件上传对象
var file = new FormData();
//console.log("长度:"+$('#fileInput')[0].files.length)
//遍历所有文件
for (var i = 0; i < $('#fileInput')[0].files.length; i++) {
//向formData对象中追加文件对象, $('#fileInput')[0].files[0]表示第一个文件,
//$('#fileInput')[0]等同于getElementById('id')[0],从当前DOM对象中取得文件对象
file.append("files", $('#fileInput')[0].files[i])
}
//将其他数据追加进FormDate,可以是任意类型
file.append("name",$("input[name='name']").val());
//ajax进行特殊处理
$.ajax({
url: 'uploadPhotoFile',
type: 'post',
//这是浏览器默认使用表单的form中的enctype="multipart/form-date",多样化数据提交格式
data: file,
//不处理数据
processData: false,
//不设置内容类型
contentType: false
})
}
</script>
后端:
@RequestMapping(value = "/uploadPhotoFile", method = RequestMethod.POST)
//MultipartFile[]部分用来接收文件,String name部分用来接收文本数据
public void uploadPhotoFile(MultipartFile[] files,String name) {
if (files.length != 0) {
//文件大小
System.out.println(file.getSize());//229185
//获取文件类型
System.out.println(file.getContentType());//image/png
//获取对象类型
System.out.println(file.getResource());//MultipartFile resource [files]
//获取源文件全名
System.out.println(file.getOriginalFilename());//风景 - 副本 .png
//获取从@RequestParam传来的对象名称
System.out.println(file.getName());//files
//判断文件格式
for (MultipartFile f : files) {
System.out.println(f.getContentType());
}
sout(name);
}
}
把MultipartFile放在实体类中也是可以的
Spring官网例子:
class MyForm {
private String name;
private MultipartFile file;
// ...
}
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(MyForm form, BindingResult errors) {
if (!form.getFile().isEmpty()) {
byte[] bytes = form.getFile().getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
获取网站的在磁盘中的绝对路径
1、web.xml配置
<!--WebUtil工具类中给属性赋值——>String param = servletContext.getInitParameter("webAppRootKey");-->
<context-param>
//工具类中给定的名称
<param-name>webAppRootKey</param-name>
//自定义名称
<param-value>MyWebUrl</param-value>
</context-param>
<!--给JVM的系统属性set新的值的类-->
<listener>
<listener-class>
org.springframework.web.util.WebAppRootListener
</listener-class>
</listener>
2、在java类中任意地方获取
//在JVM中获取系统变量
System.getProperty("MyWebUrl");
3、原理:
org.springframework.web.util.WebAppRootListener类源码
1、类初始化
public void contextInitialized(ServletContextEvent event) {
WebUtils.setWebAppRootSystemProperty(event.getServletContext());
}
2、通过全局作用域对象获取当前网站所在的根目录
public static void setWebAppRootSystemProperty(ServletContext servletContext) throws IllegalStateException {
Assert.notNull(servletContext, "ServletContext must not be null");
//获取地址,也可以在controller中手动通过获取全局作用域对象获取
String root = servletContext.getRealPath("/");
if (root == null) {
throw new IllegalStateException("Cannot set web app root system property when WAR file is not expanded");
} else {
String param = servletContext.getInitParameter("webAppRootKey");
String key = param != null ? param : "webapp.root";
//给JVM虚拟机set新的系统变量
String oldValue = System.getProperty(key);
if (oldValue != null && !StringUtils.pathEquals(oldValue, root)) {
throw new IllegalStateException("Web app root system property already set to different value: '" + key + "' = [" + oldValue + "] instead of [" + root + "] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!");
} else {
System.setProperty(key, root);
servletContext.log("Set web app root system property: '" + key + "' = [" + root + "]");
}
}
}
3、
通过MultipartFile,实现文件上传
public boolean saveFiles(MultipartFile[] files) {
for (MultipartFile file : files) {
if (!file.isEmpty()) {
InputStream in;
FileOutputStream out;
try {
String path = System.getProperty("MyWebUrl")+"WEB-INF\\upload\\" + file.getOriginalFilename();
//通过Spring包装好的InputStream,直接获取输入流
in = file.getInputStream();
out = new FileOutputStream(path);
byte[] bytes = new byte[1024 * 1024];
int readCount;
while ((readCount = in.read(bytes)) != -1) {
out.write(bytes, 0, readCount);
}
out.flush();
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
使用MultipartFile文件配置
1、applicationContext.xml文件配置
maxUploadSize:单个请求的最大上传大小。这意味着所有上传文件的总大小不能超过这个配置的最大值。默认值是无限的(值为-1)。但是我们可以通过maxUploadSize及其value属性来设置它。
maxInMemorySize:小于这个值的文件存储在内存中,否则它们将直接存储在磁盘中。默认值是10 KB(10240字节)。或者你可以通过maxInMemorySize和它的值属性对它进行定制。
<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<!-- 指定所上传文件的总大小不能超过1M。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
<property name="maxUploadSize" value="1000000"/>
<!--设置100M文件内存储存,当文件大于100M时文件将直接从客户端的硬盘读取,小于100M文件按将放在服务器内存中,让后再用getInputStream读入服务端内存-->
<property name="maxInMemorySize" value="104857600" />
</bean>
2、maven依赖
#>commons-fileupload和commons-io实际上是由apache提供的jar包,Spring将他们的功能封装在MultiPartFile类中了。
<!-- 文件上传的相关CommonsMultipartResolver -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0.1</version>
</dependency>