当前位置: 首页 > news >正文

图片上传实现

图片上传

  • change函数
  • 图片上传
    • 图片上传到服务器
    • 上传的图片在该页面中显示
    • 修改界面代码
  • 最终实现效果

change函数

这里我们先用输入框控件来举例:

姓名:<input type='text' class='name'>

在这里插入图片描述

下面我们来写 js 语句,对控件进行绑事件来获取输入框内的值,我们尝试一下 click 函数是否可以

$(".name").click(function(){alert($(".name").val())
})

点击控件后直接弹窗,发现弹窗的内容为

在这里插入图片描述

这是因为 click点击就触发事件,不往下进行,点击控件立马触发点击事件,没有在控件中输入值的机会,无法获取该控件的值,点击后才能在控件中输入值,可是这个时候获取值的操作已经结束了

所以如果要获取输入框的值的话,需要先输入再触发事件,change 函数可以做到,表示值改变再触发事件

$(".name").change(function(){alert($(".name").val())
})

此时我们点击控件再输入值,当输入完毕后会出现弹窗,弹窗内的值就是我们所需要的数值

在这里插入图片描述

图片上传

图片上传到服务器

图片上传所需要用到的控件:

<input type='file' class='file'>

在这里插入图片描述

$(".file").change(function(){console.log($(".file").val())
})

打印该控件的值内容如下:

在这里插入图片描述

(".file").val() 只有一段字符串,不是咱们需要的值,咱们需要把图片上传到项目的部署目录里,需要的是在项目的部署目录里图片的信息
而图片没办法直接直接上传到服务器,发起请求能够传输的数据只能是字符串,需要把图片进行序列化(可以存储可以传输的数据)为二进制的字节流传到服务器

js 中提供的序列化方法是表单数据序列化new FoemData() 表单数据序列化,需要把控件放入表单里,form 表单要是能够识别到控件的值的话,控件需要加 name属性值

<form class='imgbox'><input type='file' class='file' name='file'>
</form>

此外 new FormData() 是 javascript 中原生的方法只对 dom 元素起作用,需要把 jdom 元素转为 dom 元素

var value = new FormData($(".imgbox")[0])

请求成功我们打印 value,看一下输出结果
在这里插入图片描述

发现 value 实际是个对象,这时我们获取该控件的值,使用 value.get("file")

$(".file").change(function(){var value = new FormData($(".imgbox")[0])console.log(value.get("file"))

我点击控件操作了两次,第一次上传图片,第二次并没有上传图片而是点击了取消,打印结果如下:

在这里插入图片描述

从图中可以看出上传图片和上传空的区别,发现上传图片的 name 部分有该图片的名称,而上传空的 name 部分为空,如此我们便可以通过 imgbox.get("file").name 来判断用户是否上传了图片

因此前端发起请求代码:

在这里插入图片描述
upload 后端代码:

	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// TODO Auto-generated method stub//设置请求和响应的编码格式req.setCharacterEncoding("utf-8");resp.setContentType("text/json;charset=UTF-8"); resp.setCharacterEncoding("utf-8");//表单String realFileName="";//核心ApiFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload fileUpload = new ServletFileUpload(factory);//判断是否是muitipart/form-data类型if(!ServletFileUpload.isMultipartContent(req)) {//resp.getWriter().println("表单的enctype属性不是multipart/form-data类型");System.out.println("表单的enctype属性不是multipart/form-data类型");return;}//设置单个文件上传大小fileUpload.setFileSizeMax(8*1024*1024); //设置总上传文件大小fileUpload.setSizeMax(60*1024*1024);//解析请求try {List<FileItem> parseRequest = fileUpload.parseRequest(req);//获取数据for (FileItem fileItem : parseRequest) {//判断数据类型是不是普通的form表单字段if(!fileItem.isFormField()) {//上传文件String fileName = fileItem.getName();InputStream fileStream = fileItem.getInputStream();//定义保存的父路径(服务器部署的真实路径)String parentDir = this.getServletContext().getRealPath("/upload");//定义绝对路径//String parentDir = "D:\\eclipse-workspace-new\\myWish\\WebContent\\upload";//使用UUID+文件名的方式,避免文件重名realFileName = UUID.randomUUID().toString()+"-"+fileName;//创建要保存的文件File file = new File(parentDir,realFileName);//判断文件夹是否存在if(!file.getParentFile().exists()) {//创建文件夹[多级文件夹]file.madir是创建单一文件夹file.getParentFile().mkdirs();}//创建输出流OutputStream out = new FileOutputStream(file);//创建字节缓存byte[] buffer = new byte[1024];int len = -1;//一次读取1kb(1024byte),返回-1表明读取完毕while((len = fileStream.read(buffer))!=-1) {//一次写入1kb(1024byte)out.write(buffer,0, len);}System.out.println(realFileName);//冲刷流资源out.flush();//关闭流out.close();fileStream.close();}}} catch (FileUploadException e) {e.printStackTrace();}//反馈信息String json="";if(realFileName!=null && !"".equals(realFileName)) {json = "{\"msg\":\"上传成功\",\"imgurl\":\""+realFileName+"\"}";}else {json = "{\"msg\":\"上传失败\"}";}resp.getWriter().print(json);}
}

此时我们上传图片后,控制台信息打印报错:

在这里插入图片描述

这是因为我们上传图片 ajax 请求需要额外添加两个配置contenType:falseprocessData:false

其中 contenType 默认是 true 指的是文本,设置 false 那么指的是前端给后端的数据是非文本格式processData 默认是 true 指的是以对象形式上传的数据会被转换为字符串,设置 false 那么指的是以对象形式上传的数据不会被转换为字符串
加入以上两个配置信息后,即可成功上传图片,再次上传图片后的打印信息如下:

在这里插入图片描述

此时我们查看服务器项目部署目录 C:\Users\HP\eclipse-workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\web\upload 中的内容:

在这里插入图片描述

上传到服务器成功!

上传的图片在该页面中显示

我们想实现上传图片后能够在下面看到上传的是哪张图片的功能

首先需要在HTML中添加容器来放照片:

<div class='show'></div>

请求成功我们需要在该容器中放入控件中上传的照片,将该标签元素内部的HTML内容替换为图片元素,该图片的src属性需要指向图片上传到服务器的项目部署目录 ‘upload/’ 下的图片文件

$(".show").html("<img src='upload/"+value.imgurl+"'>")

我们想要从图片上传函数中获取到在服务器上的图片信息名称 value.imgurl 再放入到添加函数的参数域中传给后端,后端加入到数据库中。
由于前面打印过 (".file").val(),控件的值是该图片在客户端电脑上的路径,不能设置该控件的值只能获取该控件的值,且图片上传函数和添加函数是分开的两个函数,imgurl只在请求成功的value域中起效果。

针对这种情况现有两种解决办法:
解决办法1:将取到的 imgurl 设置为全局变量
解决办法2:添加 hidden 隐藏域

下面我们使用解决办法2:
在该页面的HTML中添加 hidden 隐藏域,前端看不到该区域但标签确实是存在的

<input type='hidden' class='imgurl'>

图片上传函数中请求成功后让该隐藏域获取到 value.imgurl 信息

success:function(value){$(".show").html("<img src='upload/"+value.imgurl+">")$(".imgurl").val(value.imgurl)
}

前端上传图片后,在前端页面中找到该标签,如下,获取到了,这样我们就能在一个页面(html标签值)中得到上传图片的信息了
在这里插入图片描述

前端图片上传函数,需要将 hidden 隐藏域携带上:
在这里插入图片描述
前端添加函数,获取 hidden 隐藏域中的值即可得到图片信息:
在这里插入图片描述

数据库中还需要添加 imgurl 字段

后端添加servlet代码:

在这里插入图片描述

修改界面代码

HTML:

<body>
修改
<div class='updateModel'>
姓名:<input type='text' class='name'><br><br>
性别:<input type='text' class='sex'><br><br>
年龄:<input type='number' class='age'><br><br>
头像:
<form class='imgbox'><input type='file' class='file' name='file'>
</form><br>
<input type='hidden' class='imgurl'>
<div class='show'></div><br>	
班级:
<select class='classid'><option value='1'>软件一班</option><option value='2'>软件二班</option><option value='3'>大数据</option><option value='4'>人工智能</option>
</select><br><br><br>自我介绍:<!-- 加载编辑器的容器 --><script id="container" name="content" type="text/plain"></script><!-- 配置文件 --><script type="text/javascript" src="utf8-jsp/ueditor.config.js"></script><!-- 编辑器源码文件 --><script type="text/javascript" src="utf8-jsp/ueditor.all.js"></script><!-- 实例化编辑器 --><input type='button' class='update' value='修改'>
</div>
</body>

js:

$(function(){//实例化编辑器var ue = UE.getEditor('container');//展示var id = $.cookie("id")$.ajax({url:"SearchById",type:"get",data:{id},success:function(value){var obj = value.data[0]$(".name").val(obj.name)$(".sex").val(obj.sex)$(".age").val(obj.age)$(".classid").val(obj.classid)$(".imgurl").val(obj.imgurl)$(".show").html("<img src='upload/"+obj.imgurl+"' style='width:250px;height:200px;object-fit:cover'>")ue.ready(function(){var introduce = ue.setContent(obj.introduce)})}})//图片上传 change值改变事件$(".file").change(function(){//表单数据序列化var imgbox = new FormData($(".imgbox")[0])if(imgbox.get("file").name){$.ajax({url:"upload",type:"post",data:imgbox,contentType:false,//非文本格式processData:false,success:function(value){console.log(value)$(".show").html("<img src='upload/"+value.imgurl+"' style='width:250px;height:200px;object-fit:cover'>")$(".imgurl").val(value.imgurl)}})}})//修改$(".update").click(function(){var name = $(".name").val()var sex = $(".sex").val()var age = $(".age").val()var classid = $(".classid").val()var introduce = ue.getContent()var imgurl = $(".imgurl").val()$.ajax({url:"UpdateServlet",type:"post",data:{name,sex,age,classid,id,introduce,imgurl},success:function(value){alert(value)location.href="index.html"}})})
})

后端:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");String name = request.getParameter("name");String sex = request.getParameter("sex");String age = request.getParameter("age");String classid = request.getParameter("classid");String id = request.getParameter("id");String introduce = request.getParameter("introduce");introduce = introduce.replace("\"", "\'");String imgurl = request.getParameter("imgurl");String sql = "update student set name = \""+name+"\",age = "+age+",sex = \""+sex+"\",classid = "+classid+",introduce=\""+introduce+"\",imgurl=\""+imgurl+"\" where id = "+id;int num = MysqlUtil.update(sql);String res = "修改失败";if(num>0) {res="修改成功";}response.getWriter().write(res);	
}

最终实现效果

在这里插入图片描述
在添加页面和修改页面都有上面图片的效果,可以上传图片并且下面会展示上传图片的缩略图。但在添加页面选择图片点击后再添加按钮,该图片会被数据库记录,在修改页面选择图片后再点击修改按钮,数据库会修改记录。

http://www.xdnf.cn/news/1139005.html

相关文章:

  • 多方案对比分析:后端数据加密策略及实践
  • Redis7 底层数据结构解析
  • Linux驱动14 --- 平台设备总线
  • JPA 与 MyBatis-Plus 数据库自增主键实现方案
  • GraphQL的N+1问题如何被DataLoader巧妙化解?
  • 【人工智能99问】梯度消失、梯度爆炸的定义、后果及规避手段?(7/99)
  • 使用位运算优化 Vue.js 应用:高效状态管理技巧
  • deep learning(李宏毅)--(六)--loss
  • 虚拟化测试工具Parasoft Virtualize如何为汽车企业提供仿真测试?
  • Helm-k8s包管理工具(一)核心概念、helm工作目录
  • 【Servo】伺服驱动器扫频功能方案文档
  • 有痛呻吟!!!
  • Redis面试相关问题总结
  • 离散与组合数学 杂记
  • 学习设计模式《十八》——备忘录模式
  • AI安全威胁之MCP Server投毒攻击实践
  • 深入理解进程等待:wait的简化与waitpid的灵活性
  • centos中新增硬盘挂载文件夹
  • 【FFmpeg 快速入门】本地播放器 项目
  • 林曦词典|文质彬彬
  • 物联网主机在化工园区安全风险智能化管控平台中的应用
  • mongodb 入门级别操作
  • 搞清MVCC
  • 优化 CSS 性能
  • 面试Redis篇-深入理解Redis缓存击穿
  • Selenium 启动的浏览器自动退出问题分析
  • 全面升级!WizTelemetry 可观测平台 2.0 深度解析:打造云原生时代的智能可观测平台
  • 杭州卓健信息科技有限公司 Java 面经
  • web前端渡一大师课 CSS属性计算过程
  • 损失函数的等高线与参数置零的关系