最近用传统的Servlet+jsp的方法实现一个上传用户头像的功能,发现比使用Springboot框架上传图片真是难多了,中间也遇到了各种各样的问题,记录一下。
上传头像
先写一个上传头像的表单
<div class="panel panel-default">
<div class="panel-heading">修改头像</div>
<div class="panel-body">
<form action="upload" method="post" enctype="multipart/form-data">
<input type="hidden" name="userID" value=<%=user.get("userID") %>>
<input type="file" name="testImg" id="headimg" onchange="show(this)"><br>
<input type="submit" value="上传头像">
</form>
<div id="touxiang">
<img class="userinfo-head" src="<%=user.get("userHead") %>" alt='头像' width="100" height="100"
id="showimg">
</div>
</div>
</div>
表单类型enctype="multipart/form-data"
为了能在选择图片之后就能预览到图片再进行上传,我们添加一段js(此处代码参考网友,具体是哪位仁兄的忘记了,见谅)
<script type="text/javascript">
function show(f) {
var reader = new FileReader();//创建文件读取对象
var files = f.files[0];//获取file组件中的文件
reader.readAsDataURL(files);//文件读取装换为base64类型
reader.onloadend = function(e) {
//加载完毕之后获取结果赋值给img
document.getElementById("showimg").src = this.result;
}
}
</script>
添加处理上传文件的servlet
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("方法开始执行了");
HttpSession session = req.getSession();
// 验证请求是否满足要求(post 请求 / enctype 是否以multipart打头
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
// 如果不满足要求就立即结束对该请求的处理
if (!isMultipart) {
return;
}
try {
// FileItem 是表单中的每一个元素的封装
// 创建一个 FileItem 的工厂类
FileItemFactory factory = new DiskFileItemFactory();
// 创建一个文件上传处理器(装饰设计模式)
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析请求
List<FileItem> items = upload.parseRequest(req);
System.out.println(items);
for (FileItem item : items) {
// 判断文件类型
if (item.isFormField()) {
// 文本类型
String filename = item.getFieldName();
if (filename.equals("userID")) {
userID = Integer.parseInt(item.getString("UTF-8"));
System.out.println(userID);
}
} else {
// 文件类型
// 获取文件后缀名
String imgtype = item.getName().substring(item.getName().lastIndexOf("."));
// 给文件重新命名防止重复
String imgName = UUID.randomUUID() + imgtype;
System.out.println();
// 将上传的文件保存到服务器
item.write(new File("E:\\eclipse-workspace1\\HPBUS_front\\WebContent\\image", imgName));
// 头像路径
userHead = "image/" + imgName;
System.out.println("头像访问路径:" + userHead);
// 将路径保存到数据库
dao.updateUserHead(userHead, userID);
System.out.println("保存成功!");
//更新Session中的用户信息
HashMap<String, String> user = dao.queryByID(userID);
session.setAttribute("loginuser", user);
req.getRequestDispatcher("news?op=index").forward(req, resp);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
问题一:因为用户登陆后用户信息就存放Session中,导致之前头像路径修改完保存到数据库了怎么刷新页面头像还是没有更新,所以这里需要重新从数据库读取修改后的用户信息后放入Session中。
问题二:为什么Session信息更新了刷新页面头像还是没有改变?因为项目是在tomcat上跑的,eclipse的目录内容改变不会自动和tomcat里的实际内容同步,所以每次上传图片后需要刷新文件夹tomcat里的项目内容才会更新。
解决:Windows->preferences->General->workspace->Refresh using native hooks or polling √
Refresh on access √
选择头像预览后上传
刷新页面,用户头像修改成功√