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

小鱼儿 2023-06-05 15:59 246阅读 0赞

功能需求描述

  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,实现图片文件路径的保存

  1. <div class="col-xs-2" align="right"> <img src="${ pageContext.request.contextPath}/image/login/userDefault.jpg" id="img"
  2. name="img" οnclick="javascript:uploadImage(this.id);"
  3. style="cursor:pointer;width:147px;height:206px;"> <input type="hidden" id="photoPath" name="photoPath" value="${ entity.photoPath}">
  4. </div>

2. 点击事件函数(此处方法给封装过的方法,用的是layui的组件,后台用的springmvc,其他框架可根据自己框架进行调整。无非就是给后台传递一个参数,然后跳转到另外一个页面)

  1. //头像图片点击函数 function uploadImage() {
  2. //弹出图片上传 var url = "${ pageContext.request.contextPath}/administration/hrManage/personInfo/toImageUploadJsp.do"; var obj = {
  3. area: ['40%', '70%'],
  4. url: url,
  5. title: '上传图片',
  6. id: 'personInfoAdd'
  7. };
  8. getDialogPage(obj);
  9. }

3. 后台处理点击后,跳转到图片上传页面的方法

  1. @RequestMapping("/toImageUploadJsp")
  2. public ModelAndView toImageUploadJsp(){
  3. ModelAndView modelAndView = new ModelAndView();
  4. try {
  5. modelAndView.addObject("formBtn", getFormBut(EditStatus.valueOf(1), false, false));//表单按钮
  6. modelAndView.setViewName("/web/administration/hrManage/imageUpload");
  7. } catch (Exception e) {
  8. log.error("跳转到跳转到图片上传页面失败",e);
  9. modelAndView.setViewName("error/500");
  10. }
  11. return modelAndView;
  12. }

4. 上传页面代码

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <!DOCTYPE>
  4. <html>
  5. <head>
  6. <title>用户签名</title>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <jsp:include page="/initlib/initCommon.jsp"></jsp:include>
  9. <jsp:include page="/initlib/initEditCss.jsp"></jsp:include>
  10. <style type="text/css">
  11. </style>
  12. </head>
  13. <body>
  14. <div style="width: 96%; height: 90%;">
  15. <legend>基本信息</legend>
  16. <hr style="margin-top:-20px;margin-left: 4%">
  17. <form id="dataForm" class="form-horizontal" role="form" method="post">
  18. <div class="form-group form-group-xs">
  19. <label for="uploadFile" class="col-xs-2 control-label"><a class="require"><i
  20. class="icon-Asterisk"></i></a>上传文件</label>
  21. <div class="col-xs-2">
  22. <input type="file" name="uploadFile" id="uploadFile" style="font-size:
  23. 10px;font-family: Microsoft YaHei;border-style: inset;border-width: 2px;padding: 1px;" οnchange="preview(this)">
  24. </div>
  25. </div>
  26. <div class="form-group form-group-xs">
  27. <label for="previewImg" class="col-xs-2 control-label"><a class="require"><i
  28. class="icon-Asterisk"></i></a>预览图片</label>
  29. <div class="col-xs-6">
  30. <img id="previewImg" style="width:147px;height:206px;"/>
  31. </div>
  32. </div>
  33. </form>
  34. <div id="footer">${ formBtn}</div>
  35. </div>
  36. </body>
  37. </html>
  38. <script>
  39. $(document).ready(function () {
  40. });
  41. function saveClick() {
  42. if ($("#uploadFile").val() == "") {
  43. layer.msg('请选择要上传的文件', { icon: 0});
  44. return;
  45. }
  46. layer.confirm('上传将会清空原有头像,是否继续操作?', {
  47. btn: ['确认', '取消'] //按钮
  48. }, function () {
  49. var index = layer.load();
  50. $.ajaxFileUpload({
  51. url: "${pageContext.request.contextPath}/administration/hrManage/personInfo/imageUpload.do",
  52. secureuri: false,
  53. fileElementId: "uploadFile",
  54. dataType: 'text',
  55. type: "POST",
  56. success: function (data, status) {
  57. layer.close(index);
  58. var res = data.substring((data.indexOf('>') + 1), (data.indexOf('}') + 1));
  59. var json = $.parseJSON(res);
  60. if (json.success) {
  61. //todo 处理返回的图片路径
  62. //parent.$("#photoPath").attr("src",json.obj);
  63. parent.initImage(json.obj);
  64. layer.msg(json.msg, { icon: 6, time: 1000}, function () {
  65. closeClick();
  66. });
  67. } else {
  68. layer.msg(json.msg, { icon: 5});
  69. }
  70. },
  71. error: function (data, status, e) {
  72. }
  73. });
  74. }, function () {
  75. }
  76. );
  77. }
  78. //预览图片
  79. function preview(obj) {
  80. var file = obj.files[0];
  81. //file.size 单位为byte 可以做上传大小控制
  82. console.log("file.size = " + file.size);
  83. var reader = new FileReader();
  84. //读取文件过程方法
  85. reader.onabort = function (e) {
  86. console.log("中断读取....");
  87. }
  88. reader.onerror = function (e) {
  89. console.log("读取异常....");
  90. }
  91. reader.onload = function (e) {
  92. var img = document.getElementById("previewImg");
  93. img.src = e.target.result;
  94. }
  95. reader.readAsDataURL(file)
  96. }
  97. </script>

Tips: 页面中包含三部分内容:
1) 添加一个file类型的输入框,用于选择本地可上传的文件。
2) 增加了一个function preview(obj)函数,用于处理上传后的图片预览功能
3) 添加一个function saveClick()函数,用于处理图片文件校验、上传图片以及图片回调问题
4)上传成功后的回调函数parent.initImage(json.obj);将在后面进行介绍

5.图片流后台保存函数

  1. @ResponseBody
  2. @RequestMapping("/imageUpload")
  3. public Json imageUpload(HttpSession session, @RequestParam("uploadFile") CommonsMultipartFile uplodaFile) {
  4. Json json = new Json();
  5. try {
  6. String contentType = uplodaFile.getContentType();
  7. String fileName = DateUtil.getNowDateTime("YYYY-MM-DD")+uplodaFile.getOriginalFilename();
  8. String folderPath = "E:/userImage";
  9. if (uplodaFile.isEmpty()) {
  10. json.setSuccess(false);
  11. json.setMsg("上传图片不正确");
  12. return json;
  13. }
  14. try {
  15. File targetFile = new File(folderPath);
  16. if (!targetFile.exists()) {
  17. targetFile.mkdirs();
  18. }
  19. FileOutputStream out = new FileOutputStream(folderPath +"/"+ fileName);
  20. out.write(uplodaFile.getBytes());
  21. out.flush();
  22. out.close();
  23. } catch (Exception e) {
  24. json.setSuccess(false);
  25. json.setMsg("上传图片失败");
  26. return json;
  27. }
  28. json.setSuccess(true);
  29. //返回图片路径
  30. json.setObj(folderPath+"/"+fileName);
  31. json.setMsg("上传图片成功");
  32. } catch (Exception e) {
  33. log.error(message, e);
  34. json.setSuccess(false);
  35. json.setMsg("上传图片失败"+e.getMessage());
  36. }
  37. return json;
  38. }
  1. 前台回调函数功能,1. 保存返回的图片路径,2. 动态加载图片

    //初始化员工头像

    1. function initImage(url) {
    2. if (url != undefined && url != "") {
    3. $("#img").attr("src", "${pageContext.request.contextPath}/administration/hrManage/personInfo/getImage.do?path=" + url);
    4. $("#photoPath").val(url);
    5. } else if ("${entity.photoPath}" != "") {
    6. $("#img").attr("src", "${pageContext.request.contextPath}/administration/hrManage/personInfo/getImage.do?path=" + "${entity.photoPath}");
    7. }
    8. }
  2. 上文中,调用了一个getImage的后台函数,是因为我们将图片保存到服务器上项目外的文件夹内,工程文件无法直接通过路径对图片进行读取。因此需要额外处理。

    @ResponseBody

    1. @RequestMapping("/getImage")
    2. public void getImage(String path, HttpServletRequest request, HttpServletResponse response) {
    3. OutputStream os = null;
    4. try {
    5. BufferedImage image = ImageIO.read(new File(path));
    6. response.setContentType("image/png");
    7. os = response.getOutputStream();
    8. ImageIO.write(image, "gif", os);
    9. } catch (IOException e) {
    10. e.printStackTrace();
    11. }
    12. }

总结

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

发表评论

表情:
评论列表 (有 0 条评论,246人围观)

还没有评论,来说两句吧...

相关阅读