如何实现多文件上传?
我的回答是使用表单或者ajax异步,异步可for来执行ajax提交,springmvc是一个非常优秀的框架,直接用它来完成即可。
下面将基于springmvc来完成,如果文件太大注意配置springMVC上传文件的max
值。
下面将演示多种上传文件的3种骚操作:
1、form提交
前端:
文件上传
后台:
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile[] files) throws IOException {
for (MultipartFile file : files) {
//判断非空
if(file.isEmpty()){
continue;//跳过本次循环
}
//文件后缀
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
//随机名称UUID
Path path= Paths.get("E:\\" + UUID.randomUUID() + suffix);
//保存到对应路径
file.transferTo(path);
}
return "success";
}
如果我想传参怎么办?
@PostMapping("/upload")
@ResponseBody
public String upload(HttpServletRequest request,MultipartFile[] files) throws IOException {
for (MultipartFile file : files) {
//判断非空
if (file.isEmpty()) {
Enumeration params = request.getParameterNames();
String p=null;
while (params.hasMoreElements()) {
//参数名称
p=params.nextElement().toString();
System.out.println(p);
//参数值
System.out.println(request.getParameter(p));
}
continue;//跳过本次循环
}
//文件后缀
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
//随机名称UUID
Path path = Paths.get("E:\\" + UUID.randomUUID() + suffix);
//保存到对应路径
file.transferTo(path);
}
return "success";
}
2、ajax异步
前端:
//js如下:
function picBtn() {
//出发点击input
$("#inputPic").click();
}
//触发回显图片
function showPicture(e) {
for (var i = 0; i < e.target.files.length; i++) {
var file = e.target.files.item(i);
if (!(/^image\/.*$/i.test(file.type))) {
continue; //不是图片 就跳出这一次循环
}
//实例化FileReader API
var freader = new FileReader();
freader.readAsDataURL(file);
freader.onload = function (e) {
$("#pic").attr("src", e.target.result);
$("#pic").show();
}
}
}
//监听提交
form.on('submit(addForm)', function (datas) {
//layer.msg(JSON.stringify(data.field));
var picFile = $('#inputPic')[0].files[0];
if (picFile == null) {
layer.msg('您还没有选择图片!', {icon: 5, anim: 6});
return false;
}
var formData = new FormData;
formData.append('picture', picFile)
formData.append('name', datas.name)
formData.append('price', datas.price)
formData.append('describe', datas.describe)
$.ajax({
data: formData,
type: 'post',
dataType: 'json',
processData: false,//不做处理
contentType: false,//不做处理
url: '/add',
error: function (data) {
layer.msg('服务器错误500。。。。', {icon: 5, anim: 6})
},
success: function (data) {
if (data.status == 'success') {
window.setTimeout("layer.msg('添加成功!')");
} else {
layer.msg(data.status, {icon: 5, anim: 6});
}
}
})
});
后端:
@PostMapping("add")
@ResponseBody
private Object add(@RequestParam("picture")MultipartFile picture){
String name=request.getParameter("name");
String price=request.getParameter("price");
String describe=request.getParameter("describe");
Map map = new HashMap<>();
if (describe.length() > 70) {
map.put("status", "描述太长了!100字符以内");
return map;
}
if (picture.getSize() > 2097152) {
map.put("status", "图片太大了!不能超过2M");
return map;
}
Menu menu = new Menu();
String fileName = picture.getOriginalFilename().toLowerCase();//小写化
String Suffix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
//判断后缀
if (!Suffix.equals(".jpg") && !Suffix.equals(".png") && !Suffix.equals(".gif") && !Suffix.equals(".jpeg")) {
map.put("status", "图片格式有误。支持:.jpg、.png、gif、jpeg");
return map;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String picName = sdf.format(new Date()) + Suffix;
menu.setPicture(picName);
BufferedOutputStream out;
try {
out = new BufferedOutputStream(new FileOutputStream(new File(savePicturePath + picName)));
out.write(picture.getBytes());
out.flush();
out.close();
} catch (Exception e) {
map.put("status", "服务器错误 " + e);
return map;
}
map.put("status", "success");
menu.setName(name);
menu.setServerPicture(serverPicturePath + picName);
menu.setDescribe(describe);
menu.setCreateTime(new Date());
menuMapper.insertSelective(menu);
return map;
}
3、最后再演示下工厂模式上传:
需要加入上传文件依赖:·2019年11月21日 最新版本依赖·
commons-io
commons-io
2.6
commons-fileupload
commons-fileupload
1.4
前端:注意使用http multipart/form-data
文件上传
后端:
如果使用springboot,默认文件上传会交给multipart导致request取不到文件 需要配置spring.servlet.multipart.enabled=false 因为关闭了spring的multipart导致没有大小限制,需要代码中限制大小
@PostMapping("/uploadFiles")
@ResponseBody
public String uploadFiles(HttpServletRequest request) throws Exception {
//注意使用org.apache.commons.fileupload下的依赖包
//创建一个解析器工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置工厂的内存缓冲区大小,默认是10K
// factory.setSizeThreshold(1024 * 1024);
//设置工厂的临时文件目录:当上传文件的大小大于缓冲区大小时,将使用临时文件目录缓存上传的文件
factory.setRepository(new File("e:\\"));
//文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//设置所有上传数据的最大值,单位字节long 20M
upload.setSizeMax(1024 * 1024 * 800);
//设置单个文件上传的最大值
upload.setFileSizeMax(1024 * 1024 * 300);
//设置编码格式
upload.setHeaderEncoding("UTF-8");
//解析请求,将表单中每个输入项封装成一个FileItem对象
List itemList = upload.parseRequest(request);
for (FileItem item : itemList) {
//判断输入的类型是 普通输入项 还是文件
if (item.isFormField()) {
//普通输入项 ,得到input中的name属性的值
String name = item.getFieldName();
//得到输入项中的值
String value = item.getString("UTF-8");
System.out.println("name=" + name + " value=" + value);
} else {
//如果file的属性小于1,即是传空文件,跳过
if (item.getSize() < 1)
continue;
//上传的是文件,获得文件上传字段中的文件名
//注意IE或FireFox中获取的文件名是不一样的,IE中是绝对路径,FireFox中只是文件名。
String fileName = item.getName();
System.out.println(fileName);
//返回表单标签name属性的值
String namede = item.getFieldName();
System.out.println(namede);
InputStream is = item.getInputStream();
FileOutputStream fos = new FileOutputStream("e:\\" + fileName);
byte[] buff = new byte[1024];
int len = 0;
while ((len = is.read(buff)) > 0) {
fos.write(buff);
}
//关闭流
is.close();
fos.close();
//清理临时文件
item.delete();
}
}
return "success";
}
以上是我的分享