一、背景:简易版SpringMVC项目(链接.do结尾)下实现文件上传
1、导入所需jar包
2、springmvc-servlet.xml文件中增加文件上传的配置
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8" />
<!-- 指定所上传文件的总大小,单位字节。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
<property name="maxUploadSize" value="10240000" />
</bean>
3、前台页面:index.jsp
<%@ page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>文件上传</title>
<meta http-equiv="Content-Type" content="multipart/form-data; charset=utf-8" />
<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
</head>
<input type="file" id="file" name="file" onchange="uploadFile(this)">
<div id="mfile"></div>
<script type="text/javascript">
function uploadFile(obj){
/* FormData对象用以将数据编译成键值对,其主要用于发送数据,append()方法来添加字段 */
var formData=new FormData();
formData.append("file",obj.files[0]);//文件上传的是个集合,因为只限制上传一个,所以直接获取第0个元素即可
alert((obj.files[0].type).split("/")[0]);
if((obj.files[0].type).split("/")[0]=="image"){
//图片
$.ajax({
url: "uploadFile.do",
type: "POST",
data:formData,
cache:false, //不设置缓存
processData: false, // 不处理数据
contentType: false , // 不设置内容类型
error: function (result) {
alert("上传图片失败");
},
success: function (result) {
var a=JSON.parse(result);
alert(a.path);
$("#mfile").append("<img width='32px' onclick=\"mpath('"+a.path+"')\" src="+a.path+">");
}
});
}else{
//文件
$.ajax({
url: "uploadFile.do",
type: "POST",
data:formData,
cache:false, //不设置缓存
processData: false, // 不处理数据
contentType: false , // 不设置内容类型
error: function (result) {
alert("上传文件失败");
},
success: function (result) {
var a=JSON.parse(result);
$("#mfile").append("<a href=\"javascript:alert('"+a.path+"')\">"+a.name+"</a>");
}
});
}
}
function mpath(pa){
alert(pa);
}
</script>
</body>
</html>
4、后台Controller:FileUpload.java
package com.file;
import java.io.File;
import java.util.HashMap;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class FileUpload {
@ResponseBody
@RequestMapping("uploadFile.do")
public String uploadImage(HttpServletRequest request,@RequestParam MultipartFile file)throws Exception {
String content = null;
ObjectMapper mapper = new ObjectMapper();
HashMap<String, Object> map = new HashMap<String, Object>();
String originalFilename=file.getOriginalFilename(); //获取文件全名【我的文件.docx】
//网络路径【http://localhost:8080/TestFile/filepath/文件名.后缀】
String oraPath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/upload/"+originalFilename;
//项目路径【C:\apache-tomcat-7.0.54\webapps\TestFile】
String mtomcat=request.getSession().getServletContext().getRealPath("/");
// 判断文件是否为空
if (!file.isEmpty()) {
File catalog=new File(mtomcat+ "/upload/");
if(!catalog.exists()){
catalog.mkdir(); //创建文件目录
}
String filepath =mtomcat + "/upload/" + originalFilename;
file.transferTo(new File(filepath)); //上传文件
map.put("path", oraPath);
map.put("name", originalFilename);
}
content = mapper.writeValueAsString(map); //writeValuesAsString方法:把对象转化成json字符格式
return content;
}
}
5、启动项目并看效果
二、拓展
1、无法多次上传同一文件
(1)大致原因:onchange是监听到input有变化时才会触发,因为上传的是同一个文件,所以对input标签来说,是没有发生改变的,即不会触发onchange,这就导致,不能多次上传同一个文件
(2)解决:在每次上传完成后,清空input的值
$("#file").val(""); //清空input值
(3)效果:上传了两个同类型同名文件
2、上传同类型同名文件,之前上传的文件内容被后面上传的文件内容覆盖
(1)大致原因:上传时,因为是同类型同文件,所以系统会认为是同一个文件,便存在内容覆盖问题
(2)解决:上传之前给文件名加个UUID(保证文件名字的唯一性:不影响前台文件的查看)
String mName=originalFilename.substring(0,originalFilename.lastIndexOf(".")); //文件名【我的文件】
String mSuffix=originalFilename.substring(originalFilename.lastIndexOf("."));//【文件后缀】
String fileName=mName+UUID.randomUUID().toString().replaceAll("-","")+mSuffix; //新文件名【我的文件xxxx.docx】
//文件路径中用新的名字
String oraPath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/upload/"+fileName;
String filepath =mtomcat + "/upload/" + fileName;
(3)效果:同类型同名文件内容没有被覆盖