【java】springMVC+eaui实现头像上传预览功能

功能需求描述

  1. 需要一个能够显示员工头像的区域,点击区域可更新图片。
  2. 图片为服务器文件存储(之所以不放到数据库中,为了防止数据库过大导致备份和迁移时效率降低)

思路描述

上传员工头像功能开发流程:

  1. 头像上传区域:
    1.1 设置头像点击事件
    1.2 设置默认头像
    1.3 在点击事件中,增加图片上传预览的弹出框
    1.4 图片上传后预览
    1.5 增加返回参数,能够返回保存到服务器上的图片路径给父页面

  2. 图片保存显示
    2.1 根据图片路径,刷新当前图片显示
    2.2 点击保存后,将最新的图片路径保存到实体内
    2.3 编辑后能正常显示头像图片信息

用到的主要技术

  1. 图片预览用到了var reader = new FileReader();渲染方法,读取本地上传的缓存图片。
  2. 图片上传需要用到文件流以及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. 前台回调函数功能,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}");
        }
    }
  1. 上文中,调用了一个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();
		}
	}

总结

  1. 处理图片上传预览,本次由于时间关系采用自行设计开发的功能页面,如果此需求其他模块均需要使用,尽量采用开源的图片上传组件,例如Web Uploader一类的。一个是页面设计更美观、合理。第二个也是方便集成
  2. 显示图片的方案,本文中采用的方式为通过文件流的形式,将服务器上存储的图片以流的形式读取到页面,并返回给前台。如果你的服务器上已经配置了nginx,建议还是用nginx配置的方式实现图片等静态资源的直接读取功能。(如果有时间,后面可以针对这一细节进行说明)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值