Java編程之如何通過JSP實(shí)現(xiàn)頭像自定義上傳
開發(fā)概述
本次項(xiàng)目意在實(shí)現(xiàn)一種可以在本地選擇圖片,然后將其上傳至服務(wù)器指定文件目錄下,并可以通過服務(wù)器自動(dòng)生成的臨時(shí)鏈接下載到本地的指定目錄進(jìn)行保存,這樣數(shù)據(jù)庫就只需要存儲對應(yīng)圖片的文件名即可進(jìn)行正常的顯示,以達(dá)到上傳圖片的目的。
開發(fā)環(huán)境
整體使用了Maven
的開發(fā)環(huán)境 數(shù)據(jù)庫操作使用的是Mybatis
進(jìn)行管理 前臺頁面的顯示操作則是通過jsp+servlet
數(shù)據(jù)庫采用mysql
數(shù)據(jù)庫
開發(fā)過程
1、JSP前臺頁面
首先你需要在你的jsp頁面中準(zhǔn)備好一個(gè)圖片上傳的<form>
表單,一開始<input>
標(biāo)簽中的value值
可以先設(shè)置為默認(rèn)值,到后面連接好數(shù)據(jù)庫,寫好servlet之后再進(jìn)行替換,這里就不在具體展示過程了,直接一步到位。另外本次舉例的具體呈現(xiàn)的效果樣式如下圖所示:
<div class="modal modal-profile" style="display: none;"> <div class="hd"><h4 class="tt" style="margin-left: 10px;">我的資料</h4><a id="a_close" class="close">×</a></div> <div class="bd"> <form class="form-horizontal" action="../usersInfo.do" method="post" enctype="multipart/form-data"> <div class="avatar"><img id="showupimg" src="img/upload/image/<%=usersInfo.getUava()%>" alt="頭像"> <a class="upload">點(diǎn)擊更換</a><input id="uploadimg" type="file" name="file" accept="image/png, image/jpeg, image/gif, image/jpg" class="upload-input"> <input type="hidden" name="uname" value="<%=usersInfo.getUname()%>"/> </div> <div class="form-group"><label class="control-label">昵稱</label> <div class="control-form"><input name="unname" type="text" placeholder="請輸入昵稱" class="form-control" value="<%=usersInfo.getUnname()%>"><!----></div> </div> <div class="form-group"><label class="control-label">簽名</label> <div class="control-form"> <textarea name="signview" rows="5" placeholder="請輸入簽名,字?jǐn)?shù)不超過100字" class="form-control"><%=usersInfo.getUpersonal()%></textarea> </div> </div> <div class="ft"> <input type="submit" id="btn_save" class="btn btn-primary" value="保存"/> <button type="button" id="btn_cancel" class="btn btn-default">取消</button> </div> </form> </div>
樣式圖:
JS操作
本來這里想通過ajax來完成的,因?yàn)橥ㄟ^servlet重定向會(huì)頁面時(shí),頁面總會(huì)閃一下,影響了用戶體驗(yàn),但是由于趕時(shí)間,就沒有把它改成ajax,以后有時(shí)間的話可能會(huì)補(bǔ)一段,現(xiàn)在先這樣吧。
$("#uploadimg").change(function () { var url, imgbase64; //獲取file對象URL if (navigator.userAgent.indexOf("MSIE") >= 1) { // IE url = document.getElementById('uploadimg').value; } else if (navigator.userAgent.indexOf("Firefox") > 0) { // Firefox url = window.URL.createObjectURL(document.getElementById('uploadimg').files.item(0)); } else if (navigator.userAgent.indexOf("Chrome") > 0) { // Chrome url = window.URL.createObjectURL(document.getElementById('uploadimg').files[0]); } // 創(chuàng)建Image對象 var image = new Image(); image.src = url; image.onload = function () { imgbase64 = getBase64Image(image); $("#showupimg").attr("src",image.src); } });
2、數(shù)據(jù)庫的設(shè)計(jì)
關(guān)于數(shù)據(jù)庫表做的其實(shí)還是比較簡單的,我做的其實(shí)是分了兩個(gè)表,一個(gè)Users
表,一個(gè)UsersInfo
表。Users表用來存放用戶的賬號、密碼和登錄時(shí)間;UsersInfo表用來存儲對應(yīng)用戶的用戶信息,如昵稱、頭像、性別、年齡等等,這里Users表用不到,所以只展示了UsersInfo表。
數(shù)據(jù)庫表:
實(shí)體類:UsersInfo.java
package com.skdsc.domain.login; public class UsersInfo { private String uname; private String unname; private Sex usex; private String uage; private String uava; private String uqq; private String upersonal; public UsersInfo() { } public UsersInfo(String uname, String unname, Sex usex, String uage, String uava, String uqq, String upersonal) { this.uname = uname; this.unname = unname; this.usex = usex; this.uage = uage; this.uava = uava; this.uqq = uqq; this.upersonal = upersonal; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public String getUnname() { return unname; } public void setUnname(String unname) { this.unname = unname; } public Sex getUsex() { return usex; } public void setUsex(Sex usex) { this.usex = usex; } public String getUage() { return uage; } public void setUage(String uage) { this.uage = uage; } public String getUava() { return uava; } public void setUava(String uava) { this.uava = uava; } public String getUqq() { return uqq; } public void setUqq(String uqq) { this.uqq = uqq; } public String getUpersonal() { return upersonal; } public void setUpersonal(String upersonal) { this.upersonal = upersonal; } }
3、數(shù)據(jù)庫操作
這里用到的數(shù)據(jù)庫操作主要是兩個(gè):findByUserInfoName()
和updateUsersInfo()
UsersMapper
import com.skdsc.domain.login.Users; import com.skdsc.domain.login.UsersInfo; import org.apache.ibatis.annotations.Param; public interface UsersMapper { Users findByUserName(@Param("parUserName") String parUserName); UsersInfo findByUsersInfoName(@Param("parUserName") String parUserName); int updateUtime(@Param("uname") String uname,@Param("newUtime") String newUtime); int updateUsersInfo(@Param("uname") String uname,@Param("newUnname") String newUnname,@Param("newUpersonal") String newUpersonal,@Param("newUava") String newUava); }
UsersMapper.xml
<mapper namespace="com.skdsc.mappers.login.UsersMapper"> <sql id="selStr">uid,uname,upwd,utime</sql> <sql id="selStr1">uname,unname,uage,usex,uava,uqq,upersonal</sql> <resultMap id="newUsersInfo" type="com.skdsc.domain.login.UsersInfo"> <result property="uname" column="uname"/> <result property="unname" column="unname"/> <result property="uage" column="uage"/> <result property="uava" column="uava"/> <result property="uqq" column="uqq"/> <result property="upersonal" column="upersonal"/> <!--嵌套對象標(biāo)簽--> <association property="usex" javaType="com.skdsc.domain.login.Sex"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> </association> </resultMap> <!-- 根據(jù)學(xué)號查詢用戶表 --> <select id="findByUserName" resultType="com.skdsc.domain.login.Users"> SELECT <include refid="selStr" /> FROM Users where uname = #{parUserName,jdbcType=VARCHAR} </select> <!-- 根據(jù)學(xué)號查詢用戶信息表 --> <select id="findByUsersInfoName" resultType="com.skdsc.domain.login.UsersInfo"> SELECT <include refid="selStr1" /> FROM UsersInfo where uname = #{parUserName,jdbcType=VARCHAR} </select> <!-- 更新最近一次的登錄時(shí)間 --> <update id="updateUtime"> UPDATE Users SET utime = #{newUtime} where uname = #{uname} </update> <!-- 更新個(gè)人資料(頭像、昵稱、個(gè)人簽名) --> <update id="updateUsersInfo"> UPDATE UsersInfo <trim prefix="set" suffixOverrides=","> <if test="newUnname !=null">unname = #{newUnname},</if> <if test="newUpersonal !=null">upersonal = #{newUpersonal},</if> <if test="newUava !=null">uava = #{newUava}</if> </trim> WHERE uname = #{uname} </update> </mapper>
4、Servlet
這里主要是先獲取<form>
表單提交上來的數(shù)據(jù),對數(shù)據(jù)進(jìn)行處理,獲得其路徑以及文件后綴,并利用年月日時(shí)分秒+8位隨機(jī)數(shù)生成一個(gè)新的文件名,最后通過DownloadImage工具類中的download方法將圖片下載到本地的指定目錄。
import static com.lazy.servlet.utils.DownloadImage.download; import static com.lazy.servlet.utils.TimeRandom.createOrderCode; @WebServlet("/usersInfo.do") @MultipartConfig public class UsersInfoAction extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String unname = request.getParameter("unname"); String upersonal = request.getParameter("signview"); String uname = request.getParameter("uname"); System.out.println(unname + upersonal + uname); try { //設(shè)置基礎(chǔ)路徑 String basePath = "http://localhost:8080/smartcampus_web_war/center/img/upload/image/"; //獲取上傳的文件 Part part = request.getPart("file"); //獲取請求的信息 String name=part.getHeader("content-disposition"); //獲取上傳文件的目錄 String root=request.getServletContext().getRealPath("/center/img/upload/image"); System.out.println("測試上傳文件的路徑:"+root); //獲取文件的后綴 String str=name.substring(name.lastIndexOf("."), name.length()-1); System.out.println("測試獲取文件的后綴:"+str); //生成一個(gè)新的文件名,不重復(fù),數(shù)據(jù)庫存儲的就是這個(gè)文件名,不重復(fù)的 String filename=root+"\\"+createOrderCode()+str; System.out.println("測試產(chǎn)生新的文件名:"+filename); //獲取上傳到本地服務(wù)器的圖片路徑 String strimg = filename.substring(filename.lastIndexOf("\\")+1); String imgsrc = basePath + strimg; System.out.println("測試獲取圖片名稱:"+strimg); //上傳文件到指定目錄,不想上傳文件就不調(diào)用這個(gè) part.write(filename); //下載到本地指定目錄 download(imgsrc, strimg,"E:\\Studyspaces\\Intellij IDEA\\IdeaProjects\\sk170403\\smartcampus_web\\src\\main\\webapp\\center\\img\\upload\\image"); SqlSession sqlSession = MybatisUtil.getSqlSession(); UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class); int updateUsersInfoflag = usersMapper.updateUsersInfo(uname,unname,upersonal,strimg); if (updateUsersInfoflag != 0){ sqlSession.commit(); }else { sqlSession.rollback(); } } catch (Exception e) { e.printStackTrace(); } response.sendRedirect("center/zfcenter.jsp"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
5、工具類
DownloadImage:下載指定路徑下的文件到本地指定目錄
package com.lazy.servlet.utils; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; public class DownloadImage { /** * @param args * @throws Exception */ public static void download(String urlString, String filename,String savePath) throws Exception { // 構(gòu)造URL URL url = new URL(urlString); // 打開連接 URLConnection con = url.openConnection(); //設(shè)置請求超時(shí)為5s con.setConnectTimeout(5*1000); // 輸入流 InputStream is = con.getInputStream(); // 1K的數(shù)據(jù)緩沖 byte[] bs = new byte[1024]; // 讀取到的數(shù)據(jù)長度 int len; // 輸出的文件流 File sf=new File(savePath); if(!sf.exists()){ sf.mkdirs(); } OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename); // 開始讀取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } // 完畢,關(guān)閉所有鏈接 os.close(); is.close(); } }
TimeRandom:生成年月日時(shí)分秒+8位隨機(jī)數(shù)
package com.lazy.servlet.utils; import java.text.SimpleDateFormat; import java.util.Date; public class TimeRandom { private static String getNowDate(){ Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); return simpleDateFormat.format(date); } private static String getRandom(){ String rand = ""; for (int i = 0; i < 8; i++){ rand = rand + (int)(Math.random()*10); } return rand; } public static String createOrderCode(){ String OrderCode = getNowDate() + getRandom(); return OrderCode; } }
6、最終效果展示
總結(jié)
到此這篇關(guān)于Java編程之如何通過JSP實(shí)現(xiàn)頭像自定義上傳的文章就介紹到這了,更多相關(guān)Java JSP頭像自定義上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java批量采集豌豆莢網(wǎng)站Android應(yīng)用圖標(biāo)和包名
這篇文章主要介紹了java批量采集豌豆莢網(wǎng)站Android應(yīng)用圖標(biāo)和包名,主要用在做主題時(shí)替換這些常見應(yīng)用的圖片,需要的朋友可以參考下2014-06-06Java優(yōu)先隊(duì)列?priority?queue
本文主要介紹了Java優(yōu)先隊(duì)列?priority?queue,優(yōu)先隊(duì)列是一種特殊的數(shù)據(jù)結(jié)構(gòu)隊(duì)列中每一個(gè)元素都被分配到一個(gè)優(yōu)先權(quán)值,出隊(duì)順序按照優(yōu)先權(quán)值來劃分。一般有兩種出隊(duì)順序高優(yōu)先權(quán)出隊(duì)或低優(yōu)先權(quán)出隊(duì),想了解具體內(nèi)容的小伙伴可以參考下文內(nèi)容,希望對你有所幫助2021-12-12解決springboot沒有啟動(dòng)標(biāo)識,啟動(dòng)類也沒有啟動(dòng)標(biāo)識的問題
這篇文章主要介紹了解決springboot沒有啟動(dòng)標(biāo)識,啟動(dòng)類也沒有啟動(dòng)標(biāo)識的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01淺談Java中Collections.sort對List排序的兩種方法
本文介紹了Java中Collections.sort對List排序的兩種方法以及Comparable 與Comparator區(qū)別,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12java實(shí)現(xiàn)圖片無損任意角度旋轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)圖片無損任意角度旋轉(zhuǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解
這篇文章主要介紹了Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解,Set接口和java.util.List接口一樣,同樣繼承自Collection接口,它與Collection接口中的方法基本一致,并沒有對Collection接口進(jìn)行功能上的擴(kuò)充,只是比Collection接口更加嚴(yán)格了,需要的朋友可以參考下2024-01-01全面詳解java代碼重構(gòu)與設(shè)計(jì)模式
這篇文章主要為大家介紹了全面詳解java代碼重構(gòu)與設(shè)計(jì)模式的全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06