【java】springMVC+eaui实现头像上传预览功能
功能需求描述
- 需要一个能够显示员工头像的区域,点击区域可更新图片。
- 图片为服务器文件存储(之所以不放到数据库中,为了防止数据库过大导致备份和迁移时效率降低)
思路描述
上传员工头像功能开发流程:
- 头像上传区域:
1.1 设置头像点击事件
1.2 设置默认头像
1.3 在点击事件中,增加图片上传预览的弹出框
1.4 图片上传后预览
1.5 增加返回参数,能够返回保存到服务器上的图片路径给父页面 - 图片保存显示
2.1 根据图片路径,刷新当前图片显示
2.2 点击保存后,将最新的图片路径保存到实体内
2.3 编辑后能正常显示头像图片信息
用到的主要技术
- 图片预览用到了
var reader = new FileReader();
渲染方法,读取本地上传的缓存图片。 - 图片上传需要用到文件流以及File对象持久化的一些方法
处理流程
核心代码
1. 设置图片显示区域,绑定点击事件uploadImage。同时,增加一个记录图片上传后返回路径的隐藏input,实现图片文件路径的保存
<div class="col-xs-2" align="right"> <img src="${ pageContext.request.contextPath}/image/login/userDefault.jpg" id="img"
name="img" οnclick="javascript:uploadImage(this.id);"
style="cursor:pointer;width:147px;height:206px;"> <input type="hidden" id="photoPath" name="photoPath" value="${ entity.photoPath}">
</div>
2. 点击事件函数(此处方法给封装过的方法,用的是layui的组件,后台用的springmvc,其他框架可根据自己框架进行调整。无非就是给后台传递一个参数,然后跳转到另外一个页面)
//头像图片点击函数 function uploadImage() {
//弹出图片上传 var url = "${ pageContext.request.contextPath}/administration/hrManage/personInfo/toImageUploadJsp.do"; var obj = {
area: ['40%', '70%'],
url: url,
title: '上传图片',
id: 'personInfoAdd'
};
getDialogPage(obj);
}
3. 后台处理点击后,跳转到图片上传页面的方法
@RequestMapping("/toImageUploadJsp")
public ModelAndView toImageUploadJsp(){
ModelAndView modelAndView = new ModelAndView();
try {
modelAndView.addObject("formBtn", getFormBut(EditStatus.valueOf(1), false, false));//表单按钮
modelAndView.setViewName("/web/administration/hrManage/imageUpload");
} catch (Exception e) {
log.error("跳转到跳转到图片上传页面失败",e);
modelAndView.setViewName("error/500");
}
return modelAndView;
}
4. 上传页面代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE>
<html>
<head>
<title>用户签名</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<jsp:include page="/initlib/initCommon.jsp"></jsp:include>
<jsp:include page="/initlib/initEditCss.jsp"></jsp:include>
<style type="text/css">
</style>
</head>
<body>
<div style="width: 96%; height: 90%;">
<legend>基本信息</legend>
<hr style="margin-top:-20px;margin-left: 4%">
<form id="dataForm" class="form-horizontal" role="form" method="post">
<div class="form-group form-group-xs">
<label for="uploadFile" class="col-xs-2 control-label"><a class="require"><i
class="icon-Asterisk"></i></a>上传文件</label>
<div class="col-xs-2">
<input type="file" name="uploadFile" id="uploadFile" style="font-size:
10px;font-family: Microsoft YaHei;border-style: inset;border-width: 2px;padding: 1px;" οnchange="preview(this)">
</div>
</div>
<div class="form-group form-group-xs">
<label for="previewImg" class="col-xs-2 control-label"><a class="require"><i
class="icon-Asterisk"></i></a>预览图片</label>
<div class="col-xs-6">
<img id="previewImg" style="width:147px;height:206px;"/>
</div>
</div>
</form>
<div id="footer">${ formBtn}</div>
</div>
</body>
</html>
<script>
$(document).ready(function () {
});
function saveClick() {
if ($("#uploadFile").val() == "") {
layer.msg('请选择要上传的文件', { icon: 0});
return;
}
layer.confirm('上传将会清空原有头像,是否继续操作?', {
btn: ['确认', '取消'] //按钮
}, function () {
var index = layer.load();
$.ajaxFileUpload({
url: "${pageContext.request.contextPath}/administration/hrManage/personInfo/imageUpload.do",
secureuri: false,
fileElementId: "uploadFile",
dataType: 'text',
type: "POST",
success: function (data, status) {
layer.close(index);
var res = data.substring((data.indexOf('>') + 1), (data.indexOf('}') + 1));
var json = $.parseJSON(res);
if (json.success) {
//todo 处理返回的图片路径
//parent.$("#photoPath").attr("src",json.obj);
parent.initImage(json.obj);
layer.msg(json.msg, { icon: 6, time: 1000}, function () {
closeClick();
});
} else {
layer.msg(json.msg, { icon: 5});
}
},
error: function (data, status, e) {
}
});
}, function () {
}
);
}
//预览图片
function preview(obj) {
var file = obj.files[0];
//file.size 单位为byte 可以做上传大小控制
console.log("file.size = " + file.size);
var reader = new FileReader();
//读取文件过程方法
reader.onabort = function (e) {
console.log("中断读取....");
}
reader.onerror = function (e) {
console.log("读取异常....");
}
reader.onload = function (e) {
var img = document.getElementById("previewImg");
img.src = e.target.result;
}
reader.readAsDataURL(file)
}
</script>
Tips: 页面中包含三部分内容:
1) 添加一个file类型的输入框,用于选择本地可上传的文件。
2) 增加了一个function preview(obj)
函数,用于处理上传后的图片预览功能
3) 添加一个function saveClick()
函数,用于处理图片文件校验、上传图片以及图片回调问题
4)上传成功后的回调函数parent.initImage(json.obj);
将在后面进行介绍
5.图片流后台保存函数
@ResponseBody
@RequestMapping("/imageUpload")
public Json imageUpload(HttpSession session, @RequestParam("uploadFile") CommonsMultipartFile uplodaFile) {
Json json = new Json();
try {
String contentType = uplodaFile.getContentType();
String fileName = DateUtil.getNowDateTime("YYYY-MM-DD")+uplodaFile.getOriginalFilename();
String folderPath = "E:/userImage";
if (uplodaFile.isEmpty()) {
json.setSuccess(false);
json.setMsg("上传图片不正确");
return json;
}
try {
File targetFile = new File(folderPath);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(folderPath +"/"+ fileName);
out.write(uplodaFile.getBytes());
out.flush();
out.close();
} catch (Exception e) {
json.setSuccess(false);
json.setMsg("上传图片失败");
return json;
}
json.setSuccess(true);
//返回图片路径
json.setObj(folderPath+"/"+fileName);
json.setMsg("上传图片成功");
} catch (Exception e) {
log.error(message, e);
json.setSuccess(false);
json.setMsg("上传图片失败"+e.getMessage());
}
return json;
}
前台回调函数功能,1. 保存返回的图片路径,2. 动态加载图片
//初始化员工头像
function initImage(url) {
if (url != undefined && url != "") {
$("#img").attr("src", "${pageContext.request.contextPath}/administration/hrManage/personInfo/getImage.do?path=" + url);
$("#photoPath").val(url);
} else if ("${entity.photoPath}" != "") {
$("#img").attr("src", "${pageContext.request.contextPath}/administration/hrManage/personInfo/getImage.do?path=" + "${entity.photoPath}");
}
}
上文中,调用了一个
getImage
的后台函数,是因为我们将图片保存到服务器上项目外的文件夹内,工程文件无法直接通过路径对图片进行读取。因此需要额外处理。@ResponseBody
@RequestMapping("/getImage")
public void getImage(String path, HttpServletRequest request, HttpServletResponse response) {
OutputStream os = null;
try {
BufferedImage image = ImageIO.read(new File(path));
response.setContentType("image/png");
os = response.getOutputStream();
ImageIO.write(image, "gif", os);
} catch (IOException e) {
e.printStackTrace();
}
}
总结
- 处理图片上传预览,本次由于时间关系采用自行设计开发的功能页面,如果此需求其他模块均需要使用,尽量采用开源的图片上传组件,例如Web Uploader一类的。一个是页面设计更美观、合理。第二个也是方便集成
- 显示图片的方案,本文中采用的方式为通过文件流的形式,将服务器上存储的图片以流的形式读取到页面,并返回给前台。如果你的服务器上已经配置了nginx,建议还是用nginx配置的方式实现图片等静态资源的直接读取功能。(如果有时间,后面可以针对这一细节进行说明)
还没有评论,来说两句吧...