圖片上傳
- 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:false
和 processData: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);
}
最終實現效果
在添加頁面和修改頁面都有上面圖片的效果,可以上傳圖片并且下面會展示上傳圖片的縮略圖。但在添加頁面選擇圖片點擊后再添加按鈕,該圖片會被數據庫記錄,在修改頁面選擇圖片后再點擊修改按鈕,數據庫會修改記錄。