一、单文件上传
Spring MVC中为文件上传提供了直接的支持,即MultipartResolver接口。
MultipartResolver 用于处理上传请求,将上传请求包装成可以直接获取文件的数据 ,从而方便操作。它有两个实现类:
StandardServletMultipartResolver -----使用了Servlet3.0标准的上传方式
CommonsMultipartResolver-------使用了Apache的commons-fileipload来完成上传
使用CommonsMultipartResolver完成文件上传的步骤
1、导入jar文件
- commons-io-2.4.jar
- commons-fileupload-1.2.2.jar
2、配置MultipartResolver
在Spring MVC配置文件中,使用CommonsMultipartResolver配置一个MultipartResolver(文件上传)解析器。
<!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5000000"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
注:
- defaultEncoding:请求的编码格式,默认为ISO-8859-1,此处设置为utf-8,
defaultEncoding必须和jsp页面的pageEncoding设置一致,以便正确读取表单的内容。 - maxUploadSize:上传文件的大小上限,单位为字节。
3、编写文件上传表单页
<form id="userForm" name="userForm" method="post"
action="${pageContext.request.contextPath}/user/add.html"
enctype="multipart/form-data">
<div>
图片: <input type="file" name="picPath" id="picPath">
</div>
</form>
注: 负责文件上传的表单编码类型必须是"multipart/form-data"类型
4、编写控制器
Spring MVC会将上传文件绑定到MultipartFile对象中,MultipartFile提供了获取上传文件内容、文件名等,最后通过其transferTo()方法将文件存储到服务器上。
/**
* 保存新增用户信息---单文件
*
* @param user
* @param session
* @return
*/
@RequestMapping(value = "/addsave.html", method = RequestMethod.POST)
public String addUserSave(User user, HttpSession session, HttpServletRequest request,
@RequestParam(value = "picPath", required = false) MultipartFile attach) {
String picPath= null; //保存到数据库的图片路径
//判断文件是否为空
if (!attach.isEmpty()) {
String path = request.getSession().getServletContext()
.getRealPath("statics" + File.separator + "uploadfiles"); // 文件存放路径
logger.info("uploadFile path========>" + path);
String oldFileName = attach.getOriginalFilename(); // 原文件名
logger.info("uploadFile oldFileName========>" + oldFileName);
String prefix = FilenameUtils.getExtension(oldFileName); // 原文件后缀
logger.info("uploadFile prefix========>" + prefix);
int fileSize = 5000000;
logger.debug("uploadFile size========>" + attach.getSize());
// 上传大小不得超过500kb
if (attach.getSize() > fileSize) {
request.setAttribute("uploadFileError", "* 上传文件不得超过500kb!");
return "useradd";
// 判断上传格式是否正确
} else if (prefix.equalsIgnoreCase("jpg") || prefix.equalsIgnoreCase("png")
|| prefix.equalsIgnoreCase("jpeg") || prefix.equalsIgnoreCase("pneg")) {
// 文件名称
String fileName = System.currentTimeMillis() + new Random().nextInt(1000000) + "_Personal.jpg";
logger.debug("new fileName=====" + attach.getName());
File targetFile = new File(path, fileName);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
// 保存
try {
attach.transferTo(targetFile);
} catch (Exception e) {
request.setAttribute("uploadFileError", "*上传失败!");
e.printStackTrace();
return "redirect:/user/useradd.html";
}
picPath= path + File.separator + fileName;
} else {
request.setAttribute("uploadFileError", "*上传图片格式不正确!");
return "redirect:/user/useradd.html";
}
}
User u = (User) session.getAttribute("user"); // 获取当前用户
user.setCreatedBy(u.getId()); // 创建者
user.setCreationDate(new Date());
// 创建日期
user.setPicPath(picPath); // 设置图片路径
logger.info("picPath============>" + picPath);
try {
// 判断是否添加成功,如果添加成功则跳转用户列表页
if (userService.add(user) > 0) {
logger.info("---------------=====>success");
return "redirect:/user/userlist.html";
}
} catch (Exception e) {
logger.info("---------------=====>error");
e.printStackTrace();
}
return "redirect:/user/useradd.html";
}
解析上传步骤:
- (1)使用MultipartFile对象作为控制器处理方法的入参,从MultipartFile对象中可以获取上传文件的相关信息。
例:
@RequestParam(value="a_idPicPath",required=false) MultipartFile attach
注: 处理文件上传的请求方式一定是POST请求,GET请求无法处理文件上传。
(2)在处理方法体内,首先通过MultipartFile对象是否为空来判断是否有上传的文件,若不为空再进行处理,否则直接进行其他数据字段的保存。
例:
if(!attach.isEmpty()){
//上传操作
}
//调用userService.add(user)方法保存新增数据
(03)进行上传前的准备工作
- 定义上传目标路径
//文件存放路径
String path=request.getSession().getServletContext().
getRealPath("statics"+File.separator+"uploadfiles");
- 获取原文件名
String oldFileName=attach.getOriginalFilename(); //原文件名
- 获取原文件后缀,对后缀进行类型判断,若不匹配则给予提示
String prefix=FilenameUtils.getExtension(oldFileName); //原文件后缀
- 获取原文件大小,与规定的上传大小进行比较,若超过规定大小,则给予提示。
if(attach.getSize()>fileSize){
request.setAttribute("uploadFileError", "* 上传文件不得超过500kb!");
return "useradd";
}
- 若满足以上规定(文件大小、文件后缀),则可以进行文件上传操作。首先定义新的文件名(当前系统时间+随机数+“_Personal.jpg”),以保证不会重复,并根据新的文件名+目标路径来创建一个File对象(该对象用来接收用户上传的文件流),若不存在,则自动创建。
String fileName=System.currentTimeMillis()+new Random().nextInt(1000000)+"_Personal.jpg";
File targetFile=new File(path,fileName);
if(!targetFile.exists()){
targetFile.mkdirs();
}
- 然后调用MultipartFile对象的transferTo(targetFile)方法,把MultipartFile中文件流的数据输出到目标文件中。
attach.transferTo(targetFile);
- 将图片路径保存到数据库
二、多文件上传
实现多文件上传,只需要修改入参MultipartFile为数组,例
@RequestParam(value="attachs",required=false) MultipartFile[] attachs
在方法体内对该数组进行循环遍历,然后逐一步进行非空判断,从未进行文件上传操作。在多文件上传中, MultipartFile[] 数组里存放的文件对象,是按照Form表单的file标签顺序进行存储的,所以需要进行判断,并记录各自上传路径。
注:
- 在多文件上传中,若入参对象MultipartFile为数组,则参数前必须要加上@RequestParam注解,否则会报错。
- 若在多文件上传操作中入参对象为MultipartFile为数组,则多个file标签中的name属性值必须一致。
- 多文件上传操作也可采用单独逐个入参,file标签的name属性值不同。
例:
@RequestMapping(value="/addsave.html",method=RequestMethod.POST)
public String addUserSave(User user,HttpSession session,HttpServletRequest request,
@RequestParam(value="picPath1",required=false) MultipartFile picPath1,
@RequestParam(value="picPath2",required=false) MultipartFile picPath2){
//方法体省略,(分别进行两个文件的上传操作和数据库相应字段的更新)
}