图片上传实现

图片上传

  • 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.pswp.cn/bicheng/89585.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PTA数据结构 | C语言版】多叉堆的上下调整

本专栏持续输出数据结构题目集&#xff0c;欢迎订阅。 文章目录题目代码题目 请编写程序&#xff0c;将 n 个已经满足 d 叉最小堆顺序约束的数据直接读入最小堆&#xff1b;随后将下一个读入的数据 x 插入堆&#xff1b;再执行删顶操作并输出删顶的元素&#xff1b;最后顺次输…

selenium后续!!

小项目案例:实现批量下载网页中的资源根据15.3.2小节中的返回网页内容可知,用户只有获取了网页中的图片url才可以将图片下载到*在使用selenium库渲染网页后,可直接通过正则表达式过滤出指定的网页图片&#xff0c;从而实现批量下载接下来以此为思路来实现一个小项目案例。项目任…

深度解析Linux文件I/O三级缓冲体系:用户缓冲区→标准I/O→内核页缓存

在Linux文件I/O操作中&#xff0c;缓冲区的管理是一个核心概念&#xff0c;主要涉及用户空间缓冲区和内核空间缓冲区。理解这两者的区别和工作原理对于高效的文件操作至关重要。 目录 一、什么是缓冲区 二、为什么要引入缓冲区机制 三、三级缓冲体系 1、三级缓冲体系全景图…

【每日算法】专题十三_队列 + 宽搜(bfs)

1. 算法思路 BFS 算法核心思路 BFS&#xff08;广度优先搜索&#xff09;使用 队列&#xff08;Queue&#xff09;按层级顺序遍历图或树的节点。以下是 C 实现的核心思路和代码模板&#xff1a; 算法框架 #include <queue> #include <vector> #include <un…

【动手实验】发送接收窗口对 TCP传输性能的影响

环境准备 服务器信息 两台腾讯云机器 t04&#xff08;172.19.0.4&#xff09;、t11&#xff08;172.19.0.11&#xff09;&#xff0c;系统为 Ubuntu 22.04&#xff0c;内核为 5.15.0-139-generic。默认 RT 在 0.16s 左右。 $ ping 172.19.0.4 PING 172.19.0.4 (172.19.0.4) …

28、鸿蒙Harmony Next开发:不依赖UI组件的全局气泡提示 (openPopup)和不依赖UI组件的全局菜单 (openMenu)、Toast

目录 不依赖UI组件的全局气泡提示 (openPopup) 弹出气泡 创建ComponentContent 绑定组件信息 设置弹出气泡样式 更新气泡样式 关闭气泡 在HAR包中使用全局气泡提示 不依赖UI组件的全局菜单 (openMenu) 弹出菜单 创建ComponentContent 绑定组件信息 设置弹出菜单样…

让老旧医疗设备“听懂”新语言:CAN转EtherCAT的医疗行业应用

在医疗影像设备的智能化升级中&#xff0c;通信协议的兼容性常成为工程师的“痛点”。例如&#xff0c;某医院的移动式X射线机采用CAN协议控制机械臂&#xff0c;而主控系统基于EtherCAT架构。两者协议差异导致数据延迟高达5ms&#xff0c;影像定位精度下降&#xff0c;甚至影响…

ubuntu基础搭建

ubuntu上docker的搭建 https://vulhub.org/zh 网站最下面找到开始使用&#xff0c;有搭建的命令//安装docker&#xff0c;连接失败多试几次 curl -fsSL https://get.docker.com | sh //验证Docker是否正确安装&#xff1a; docker version //还要验证Docker Compose是否可用&am…

动态规划 + DFS + 记忆化!Swift 解 LeetCode 329 的实战笔记

文章目录摘要描述题解答案题解代码分析代码解析示例测试及结果时间复杂度空间复杂度总结摘要 这篇文章带你用 Swift 实战一道非常经典的 DFS 记忆化搜索题目 —— LeetCode 329《矩阵中的最长递增路径》。看似一个简单的“走格子”游戏&#xff0c;实则考察了搜索顺序、剪枝策…

046_局部内部类与匿名内部类

一、局部内部类&#xff08;Local Inner Class&#xff09; 1.1 定义与基本概念 局部内部类是定义在方法、构造器或代码块内部的类&#xff0c;其作用域仅限于所在的局部范围&#xff08;定义它的方法、构造器或代码块&#xff09;&#xff0c;超出该范围则无法访问。 它的核心…

Jenkins Pipeline 中使用 JsonSlurper 报错:cannot find current thread

Jenkins Pipeline 中使用 JsonSlurper 报错&#xff1a;cannot find current thread&#x1f31f; 背景⚠ 问题重现&#x1f9e0; 原因解析&#xff1a;CPS 与非 CPS 安全方法冲突✅ 解决方案一&#xff1a;使用 NonCPS 注解&#xff08;经典方案&#xff09;✅ 解决方案二&…

Go 语言循环语句详解

Go 语言循环语句详解 在编程语言中&#xff0c;循环语句是实现重复执行某些代码块的关键元素。Go 语言作为现代编程语言之一&#xff0c;提供了多种循环结构来满足不同的编程需求。本文将详细讲解 Go 语言中的循环语句&#xff0c;包括 for、while 和 goto 语句&#xff0c;帮助…

day30——零基础学嵌入式之进程间通信1.0

一、进程间通信7种方式1.传统的进程间通信方式&#xff08;1&#xff09;管道①无名管道&#xff1a;②有名管道&#xff1a;&#xff08;2&#xff09;③信号&#xff08;3&#xff09;system Ⅴ 》系统Ⅴ 进程间通信方式 inner Process Comunication④共享内存 &#xff…

408考研逐题详解:2010年第33题——网络体系结构

2010年第33题 下列选项中&#xff0c;不属于网络体系结构所描述的内容是&#xff08; &#xff09; A. 网络的层次 \qquad B. 每层使用的协议 \qquad C. 协议的内部实现细节 \qquad D. 每层必须完成的功能 解析 本题属于计算机网络基础知识的范畴&#xff0c;考查网络体系结构…

VR 远程系统的沉浸式协作体验​

在传统的远程协作中&#xff0c;团队成员往往通过二维的视频画面进行交流&#xff0c;这种方式虽然能实现基本的沟通&#xff0c;但缺乏真实感和互动性。而 VR 远程系统的出现&#xff0c;彻底改变了这一局面。戴上 VR 设备&#xff0c;员工们仿佛置身于同一个真实的办公室空间…

记录DataGrip 2025.1.3破解失败后,无法重启问题修复

记录DataGrip 2025.1.3破解失败后&#xff0c;无法重启问题修复安装过程复盘异常场景解决方式总结安装过程 在官网下载了最新版本2025.1.3。安装成功后&#xff0c;使用30天试用方式&#xff0c;打开datagrip。 复盘异常场景 网上搜索破解教程进行破解。找了一个需要现在ja…

私有服务器AI智能体搭建配置选择记录

在搭建私有服务器上的AI智能体时&#xff0c;需要从多个方面进行选择和规划&#xff0c;以确保系统性能、安全性、可扩展性等方面满足需求。1. 硬件选择 服务器配置&#xff1a; CPU&#xff1a;选择高性能多核CPU&#xff08;如Intel Xeon或AMD EPYC系列&#xff09;&#xff…

SDC Specical check setting的描述 - false path

在上一篇文中描述了SDC的基本语法&#xff0c;其中关于时序异常约束并没有进行详细的描述&#xff0c;但是在正常的设计中&#xff0c;一般这种异常的设置反而是需要特别关注的&#xff0c;主要包括&#xff1a;1. 虚假路径- false path不需要满足任何时序要求的路径&#xff1…

【Python练习】048. 编写一个函数,实现简单的命令行接口,接受用户输入并响应

048. 编写一个函数,实现简单的命令行接口,接受用户输入并响应 在 Python 中,可以通过 input() 函数创建一个简单的命令行接口,接受用户输入并根据输入内容进行响应。 示例代码 def simple_command_line_interface():"""实现一个简单的命令行接口,接受用…

软件工厂语境下的知识系统选型:兼顾合规性与集成深度

在过去几十年间&#xff0c;制造业从“工匠手作”迈向“工业流水线”&#xff0c;完成了生产效率的巨大飞跃。当软件开发也面临交付复杂性、合规要求与协作成本不断上升的现实&#xff0c;“软件工厂”的理念逐步兴起。 在这场“开发现代化”的转型中&#xff0c;知识管理被重新…