在javaweb中,使用ajax实现文件上传预览
1.表单:

-设置input type="file",multiple="multiple"可以选择多个文件,id是用来获取element,上面的hidden是用来保存字段值,即保存最终的文件名称,可能是多个
2.js:
<script type="text/javascript">
var inputEle = document.getElementById('file1');
inputEle.onchange = function (e) {
var formData = new FormData();
for (var i = 0; i < this.files.length; i++) {
var file = this.files[i];
console.log(file);
formData.append('file', file);
};
formData.append('eId', ${dInfo.enterpriseId});
// formData.append(其他参数)
if(this.files.length > 0){ //有文件就call后台,没有就不call
var type="handleagreementattachment";
var falg="fileFlag1";
fileUpload(formData,type,falg);
}
}
//文件上传,call后台
function fileUpload(formData,type,flag) {
$.ajax({
url: "${ctx}/file/fileUtil/FileUpload",
type: 'POST',
cache: false,
processData: false,
contentType: false,
enctype:"multipart/form-data",
dataType:"json",
data: formData,
async:false,
error: function (request) {
alert("服务器故障");
},
success: function (data) {
console.log(data); //wasterwatermonitorattachment
var fileValue = $("#"+ type +"").val();
for(var i=0;i<data.length;i++){
fileValue += data[i]["fileName"]+";";
//回显预览
var radom = Math.random().toString(36).substring(2);
$("#"+ flag +"").append("<li id='"+ radom +"'><a href='"+ data[i]["fileAdd"]+data[i]["fileName"] +"' style='width:60px;' title="+ data[i]["fileName"] +">" +
"<img src='${ctxStatic}/hb/fileimages/"+ data[i]["type"] +".png' alt='' style='margin-bottom: 10px'/><b>"+ data[i]["shortName"] +"</b></a>" +
"<b style='color:red;cursor:pointer;' onclick=delFile('"+ radom +"','"+ data[i]["fileName"] +"','"+ type +"');>删除</b></li>");
}
$("#"+ type +"").val(fileValue);
}
});
}
//删除文件
function delFile(id,name,type) {
var a = confirm("确认删除 " + name + " 吗?");
if(a==true){
var node = document.getElementById(id);
node.remove(); //删除这个节点
var value = $("#"+ type +"").val(); //获取本来的字段值
value = value.replace(name+";",""); //删除其中的某个文件
$("#"+ type +"").val(value); //重新赋值
return true;
}else{
return false;
}
}
</script>
要注意这一块script要放到<body>的最下面,否则会导致 inputEle 获取不到element,因为页面没有加载完成;ajax call的时候只需要传递 formData 就可以了,我这边是业务需求所以多了几个对象。
3.java后台接收并处理文件,接收的时候可以debug一下,这里可以获取到很多的文件属性。我这边写了一个公用的后台,不管哪里使用,直接call这里就好了。
这里上传的文件可能是多个 MultiparFile[] 来接收文件参数,返回给前端的是一个文件对象的集合,业务需要,所以用文件对象来存储文件的各种属性。
package com.zhouhe.modules.myUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* 文件上传
* @Author zhouhe
* @Date 2019/12/5 13:07
*/
@Controller
@RequestMapping(value = "${adminPath}/file/fileUtil")
public class FileController {
/**
* 文件上传,ajax 方式
* @param request
* @param model
* @param file
* @return
*/
@ResponseBody
@RequestMapping(value="/FileUpload", method = RequestMethod.POST)
public List<FileEntity> FileUpload(HttpServletRequest request, Model model,@RequestParam(value="file",required=false) MultipartFile[] file) {
// List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
String eId = request.getParameter("eId"); //企业 id
List<FileEntity> fileList = FileUpload.uploadFiles(file,eId);
return fileList;
}
}
4.下面是调用文件上传Util
package com.zhouhe.modules.myUtils;
import com.zhouhe.modules.api.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 文件上传 ajax 方式
* @Author zhouhe
* @Date 2019/12/5 13:12
*/
public class FileUpload {
private static Logger logger = LoggerFactory.getLogger(FileUpload.class);
public static final String FILE_URL = Constants.LOCAL_FILE_URL; //本地路径
// public static final String FILE_URL = Constants.BASE_FILE_URL; //服务器部署路径
/**
* 多个文件上传,循环调用单个文件上传的方法
* @param file
* @param folder
* @return
*/
public static List<FileEntity> uploadFiles(MultipartFile[] file,String folder){
String fileFolder = FILE_URL+ "ea/" + folder; //一起一档的文件目录是 基础目录 + ea + 企业id
List<FileEntity> fileList = new ArrayList<FileEntity>();
File isFolder = new File(fileFolder);
if (!isFolder.exists()) {
isFolder.mkdirs();
}
for(int i=0;i<file.length;i++){
fileList.add(uploadFile(file[i],fileFolder,folder));
}
return fileList;
}
/**
* 上传文件(单个)
* 1.Constants.LOCAL_FILE_URL 是本地文件存储路径,部署要换成 Constants.BASE_FILE_URL
* 2.jsp 表单提交的时候要设置 method="post" enctype="multipart/form-data"
* 3.要在 springmvc 中有对上传文件的大小做限制
* 4.要考虑传递过来的是多个文件问题,暂时没有实现
*
* @param upFile 页面传过来的文件
* @param fileFolder 上传文件的全路径
* @param folder 存储的文件夹 这里是企业id
* @return 文件对象
*/
public static FileEntity uploadFile(MultipartFile upFile,String fileFolder, String folder){
//定义返回对象,返回文件对象
FileEntity f = new FileEntity();
if (upFile.getSize() > 0) {
// 得到文件的原始名称,如:美女.png
String fileName = upFile.getOriginalFilename();
File file = new File(fileFolder,fileName);
try {
upFile.transferTo(file); //上传文件
String fileRoute = Constants.DOWNLOAD_URL +"ea/"+folder+"/"; //文件下载路径,服务器路径
f.setFileAdd(fileRoute);
f.setFileName(fileName); //文件名
f.setShortName(shortName(fileName)); //文件缩略名
f.setSuffix(fileName.substring(fileName.lastIndexOf(".") + 1)); //后缀
f.setType(getType(fileName.substring(fileName.lastIndexOf(".") + 1))); //文件类型
return f; //返回文件对象
} catch (IOException e) {
e.printStackTrace();
logger.debug("上传文件失败");
}
}
return null;
}
/**
* 文件缩略名
* 保留4个字符,后面用 ... 代替
* @param name
* @return
*/
public static String shortName(String name){
if(name.length() > 4){
String str = name.substring(4,name.length());
name = name.replace(str,"...");
}
return name;
}
/**
* 根据文件后缀判断文件类型
* @param name
* @return
*/
public static String getType(String name){
if ("pdf".equals(name)) {
return "pdf";
} else if ("excel".equals(name)) {
return "excel";
} else if ("xls".equals(name)) {
return "excel";
} else if ("xlsx".equals(name)) {
return "excel";
} else if ("docx".equals(name)) {
return "word";
} else if ("doc".equals(name)) {
return "word";
} else if ("png".equals(name)) {
return "png";
} else if ("jpg".equals(name)) {
return "png";
} else if ("jpeg".equals(name)) {
return "png";
} else if ("rar".equals(name)) {
return "zip";
} else if ("ppt".equals(name)) {
return "ppt";
} else if ("pptx".equals(name)) {
return "ppt";
}else {
return "txt";
}
}
}
5.文件属性类
package com.zhouhe.modules.myUtils;
/**
* 文件属性类
* @Author zhouhe
* @Date 2019/12/3 16:17
*/
public class FileEntity {
private String fileName; //文件名称
private String shortName; //文件缩略名
private String fileAdd; //文件地址
private String suffix; //文件后缀
private String type; //文件类型
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileAdd() {
return fileAdd;
}
public void setFileAdd(String fileAdd) {
this.fileAdd = fileAdd;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}
6.文件预览的话只需要把文件属性传递到页面即可
