1、文件上传三要素
-
表单必须使用POST提交
-
表单必须指定enctype="multipart/form-data"
-
必须使用input type="file"文件域,要指定name属性
enctype="application/x-www-form-urlencoded"
表单中数据以键值对的方式发送的
enctype="multipart/form-data"
表单分成不同的部分传递,整个表单由多个部分组成
2、Servlet中上传的Part接口
注:Tomcat7不支持这个接口中的方法
注解 | 作用 |
---|---|
@MultipartConfig | 在Servlet类上使用这个注解,告诉这个Servlet 浏览器表单编码类型是multipart/form-data,要改变获取数据的方式 从而可以获取到数据 |
HttpServletRequest接口 | 说明 |
---|---|
Part getPart(String name) | 获取表单中一个部分(项),主要用于获取文件部分 参数:表单项的名字 |
Part接口 | 说明 |
---|---|
String getSubmittedFileName() | 获取提交的文件名 |
void write(String fileName) | 将文件写到服务器上,相当于上传文件 |
void delete() | 删除上传过程中生成的临时文件 |
3、 代码
设置表单:enctype="multipart/form-data"
<form action="user" method="post" enctype="multipart/form-data">
<div id="two" class="tab-pane">
<div class="new-photo">
<p>当前头像:</p>
<div class="upload">
<img id="userPhoto" width="100" height="100" src="${empty currentUser.pic?'img/photo_icon.png':currentUser.pic}">
<input type="file" id="pic" name="pic" onchange="changeImg(this)"/>
</div>
</div>
</div>
<script type="text/javascript">
function changeImg(file) {
//获取上传文件对象
let obj = file.files[0];
//根据上传文件图片对象在浏览器内存里创建预览图片
let wuc = window.URL.createObjectURL(obj);
//将预览图片设置到预览位置显示
$("#userPhoto").attr('src', wuc);
//当预览图片显示加载后,释放内存预览图片对象
$("#userPhoto").load(function () {
window.URL.revokeObjectURL(wuc);//当图片加载后,释放内存空间
});
}
</script>
完善UserServlet修改的代码
-
在UserServlet上添加@MultipartConfig注解
-
在调用业务方法更新之前上传文件
-
获取文件对象Part对象
-
获取文件名,判断文件名是否为空串,如果不为空串才上传。
-
使用工具类随机生成文件名,再与原来的扩展名拼接得到唯一的新的文件名
-
获取服务器真实路径,拼接新的文件名上传到服务器上
-
给user对象设置图片的地址,保存到数据库中
-
-
根据uid查询service,将用户信息放到到session中 (代码前面已经写了)
-
重定向到用户中心回显,地址是:user?action=userInfo (代码前面已经写了)
UserServlet代码
/*
更新用户信息
*/
@SneakyThrows
protected void updateInfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 接收请求参数map
Map<String, String[]> map = request.getParameterMap();
//2. 封装成user对象
User user = new User();
BeanUtils.populate(user, map);
//-------上传文件---------
//1. 获取文件对象Part对象
Part part = request.getPart("pic");
//2. 获取文件名,判断文件名是否为空串,如果不为空串才上传。
String submittedFileName = part.getSubmittedFileName(); //cart.jpg
//注:要判断上传的文件名是否为空串
if (!"".equals(submittedFileName)) {
//3. 使用工具类随机生成文件名,再与原来的扩展名拼接得到唯一的新的文件名
String uuid = UuidUtils.simpleUuid(); //字符串:8b83ea6440d411eb92cf8c16453805b0
//获取"点"开始到最后的字符串
String ext = submittedFileName.substring(submittedFileName.lastIndexOf(".")); //.jpg
//生成新的文件名
String picName = uuid + ext; //8b83ea6440d411eb92cf8c16453805b0.jpg
//4. 获取服务器真实路径,拼接新的文件名上传到服务器上
String realPath = getServletContext().getRealPath("/img/"); //webapp/img 的真实地址
part.write(realPath + picName); //webapp/img/8b83ea6440d411eb92cf8c16453805b0.jpg
//注意:是上传到target目录下,如果清除了target,文件就被删除了
//删除临时文件
part.delete();
//5. 给user对象设置图片的地址,保存到数据库中
//-------上传结束---------
user.setPic("img/" + picName);
System.out.println("上传文件成功:" + picName);
}
//3. 调用service更新
userService.updateInfo(user);
//4. 根据uid查询用户信息,放在会话域中。注:uid要从表单中提交过来
User u = userService.findByUid(user.getUid());
request.getSession().setAttribute("currentUser", u);
//5. 重定向到用户中心回显,调用user?action=userInfo的方法
response.sendRedirect(request.getContextPath() + "/user?action=userInfo");
}