Web應用程序
WEB丝格,在英語中web即表示網(wǎng)頁的意思,它用于表示Internet主機上供外界訪問的資源碴萧。Internet上供外界訪問的Web資源分為:
1.靜態(tài)web資源(如html 頁面):指web頁面中供人們?yōu)g覽的數(shù)據(jù)始終是不變乙嘀。
靜態(tài)web資源開發(fā)技術:HTML+CSS+Javascript
2.動態(tài)web資源:指web頁面中供人們?yōu)g覽的數(shù)據(jù)是由程序產(chǎn)生的,不同時間點 訪問web頁面看到的內(nèi)容各不相同
動態(tài)web資源開發(fā)技術:JSP/Servlet
在Java中破喻,動態(tài)web資源開發(fā)技術統(tǒng)稱為Javaweb虎谢。
學習web開發(fā),需要先安裝一臺web服務器曹质,然后再在web服務器中開發(fā)相應的web資源婴噩,供用戶使用瀏覽器訪問。
WEB應用程序指供瀏覽器訪問的程序羽德,通常也簡稱為web應用几莽。一個web應用由多個靜態(tài)web資源和動態(tài)web資源組成。Web應用開發(fā)好后宅静,若想供外界訪問章蚣,需要把web應用所在目錄交給web服務器管理。
Web服務器是指駐留于因特網(wǎng)上某種類型計算機的程序姨夹,是可以向發(fā)出請求的瀏覽器提供文檔的程序纤垂。
圖片1.png
BC/CS
CS:客戶機/服務器 結構? 網(wǎng)絡游戲客戶端矾策,QQ等
BS:瀏覽器/服務器 結構? 百度,淘寶峭沦,新浪
Web應用:基于HTTP協(xié)議的應用程序
屬于 B/S架構
瀏覽器客戶端:通過HTTP協(xié)議向服務器發(fā)出請求
服務器:通過HTTP協(xié)議向客戶端響應結果
HTTP協(xié)議:
是由W3C制定的一種網(wǎng)絡應用層協(xié)議贾虽,規(guī)定了瀏覽器和web服務器之間如何通信
以及通信的數(shù)據(jù)格式
特點:一次請求,一次連接
優(yōu)點:利用有限的連接吼鱼,為近可能多的請求服務
http.png
Tomcat:開源的Java Web服務器
tomcat目錄結構
bin:主要存放一些可執(zhí)行文件(比如啟動startup.bat以及關閉的shutdown.bat)
conf:配置文件蓬豁;
lib:第三方依賴jar包;
logs:日志目錄蛉抓;
temp:臨時文件目錄庆尘;
work:jsp經(jīng)過翻譯成Servlet再翻譯成.class的文件等;
webapps:真正的web應用可以部署的位置巷送;
測試Tomcat服務器是否可以正常運行
配置環(huán)境變量
1.名稱:JAVA_HOME
變量值: jdk 的路徑(例:C:\Program Files (x86)\Java\jdk1.8.0_111)
2.名稱:CLASS_PATH
變量值:%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
3.系統(tǒng)環(huán)境變量中有一個path選中后選擇編輯
;%JAVA_HOME%\bin;
進入 tomcat 的 bin 目錄驶忌,然后雙擊 startup.bat 。
Web項目的創(chuàng)建以及配置Tomcat
c1.gif
填寫項目名稱 - version 2.5 -Next
c2.gif
目錄結構
c3.gif
配置Tomcat
Window - Preferences - Server - Runtime - Add
選擇需要配置Tomcat的版本 Tomcat 8.0
點擊 Next? - Browser
選擇相應版本的Tomcat所在本地路徑
測試是否配置成果
在WebContent下 創(chuàng)建index.html
將項目部署到Tomcat內(nèi)
啟動Tomcat服務器
通過瀏覽器訪問 localhost:8080/項目名/index.html
Web server只能訪問靜態(tài)資源笑跛,為了提高是服務的擴張性付魔,使用Servlet
什么是Servlet:
Java Servlet是和平臺無關的服務器端組件,它運行在Servlet容器中飞蹂。Servlet容器負責Servlet和客戶的通信以及調(diào)用Servlet的方法几苍,Servlet和客戶的通信采用“請求/響應”的模式。
Servlet本質(zhì)就是一個運行在Servlet容器中的Java類陈哑,Servlet容器就是Tomcat
Servlet的作用
創(chuàng)建并返回基于客戶請求的動態(tài)HTML頁面妻坝。
與其它服務器資源(如數(shù)據(jù)庫或基于Java的應用程序)進行通信
創(chuàng)建Servlet : 繼承HttpServlet,實現(xiàn)doGet( ),doPost( )方法
通過提交表單 訪問Servlet
設計表單:文本框惊窖,按鈕
屬性method 表示提交表單的方法
Get: - -doGet( )
采用路徑傳參刽宪,參數(shù)在傳遞過程中可見(地址欄)
隱私性差
傳參能力有限,只能傳少量參數(shù)
所有的請求默認都是GET請求
Post:- - doPost( )
采用實體內(nèi)容傳參界酒,參數(shù)在傳遞過程中不可見
隱私性好
實體內(nèi)容專門用來傳參圣拄,大小不受限制
在form上加method="post"
瀏覽器發(fā)送請求后,如何找到Servlet
配置web.xml
2.0 web項目會自動創(chuàng)建該文件
Servlet1//指定servlet類的唯一標識
test.Servlet1//servlet的全類名(包名.類名)
//設定servlet與客戶端的映射路徑
Servlet1//與中保持一致
/Servlet1//用于設定請求路徑
3>關于Servlet路徑配置問題詳解
路徑匹配:
/AServlet? ? ? ? --http://localhost:8080/項目名/AServlet
/ABC/AServlet? ? ? --http://localhost:8080/項目名/ABC/AServlet
/ABC/ABC/AServlethttp://localhost:8080/項目名/ABC/ABC/AServlet
/ABC/ABC/*? --http://localhost:8080/項目名/ABC/ABC/任意
/* --http://localhost:8080/項目名/任意
/ 相當于 /*
后綴名匹配:? ? ? ? ? ? *.do==> struts? ? ? ? ? ? *.action ==> struts2? ? ? ? ? ? *.html ==>
Servlet的生命周期
①服務器加載Servlet
②創(chuàng)建Servlet實例
--只有第一次請求Servlet時毁欣,創(chuàng)建Servlet實例庇谆,調(diào)用構造器
③初始化init()
--只被調(diào)用一次,在創(chuàng)建好實例后立即被調(diào)用凭疮,用于初始化當前Servlet
④service()處理用戶請求
--可以被多次調(diào)用饭耳,每次請求都會調(diào)用service方法,實際用于響應請求的哭尝,根據(jù)用戶請求的類型(get或者post)哥攘,調(diào)用doGet或者doPost方法。
⑤destory()銷毀
--只被調(diào)用一次,在當前Servlet所在的WEB應用被卸載前調(diào)用逝淹,用于釋放當前Servlet所占用的資源
//設置加載時機耕姊,默認訪問servlet時加載
//值為1時,啟動過程中便開始加載
//多個servlet之間值越小栅葡,越優(yōu)先
Servlet運行原理
s1.png
request對象
1.提取客戶端提交表單的信息
2.提取HTTP請求報頭的信息
3.在服務器段保存數(shù)據(jù)茉兰,進行數(shù)據(jù)傳遞
4.處理Web資源跳轉
HttpServletRequest常用的方法:StringgetParameter(Stringname)--根據(jù)請求參數(shù)的名字,返回參數(shù)值欣簇,特別常用
產(chǎn)生亂碼的原因:瀏覽器的編碼格式和服務器的解碼格式不同
解決亂碼:只要確保編碼和解碼一致,就絕對沒有問題
Get修改Tomcat配置文件规脸,Server.xml第65行加 URIEncoding="UTF-8"? ? POST因為Post解碼是在第一次調(diào)用getParameter之前,那么解決亂碼只需要在調(diào)用該方法之前設置編碼:? ? ? ? ? ? request.setCharacterEncoding("UTF-8");
獲取HTTP請求頭信息
1.請求行
2.請求頭
3.請求空行
4.請求數(shù)據(jù)
? ? request.getMethod(): 請求方式
? ? request.getRequestURI(): /項目名/Servlet映射名
? ? request.getServletPath(): /Servlet映射名
? ? request.getContextPath(): /項目名
? ? request.getScheme(): http
設置響應信息 response對象
1.設置響應信息的字符集
2.向客戶端響應信息
3.Web資源跳轉
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");//設置響應內(nèi)容的類型? ? ? ??
PrintWriter pw=response.getWriter();//獲取輸出流 ,向瀏覽器響應信息? ? ? ??
String html=""? ? ? ? ? ? ? ? +""? ? ? ? ? ? ? ? +""? ? ? ? ? ? ? ? +"Insert title here"? ? ? ? ? ? ? ? +""? ? ? ? ? ? ? ? +""? ? ? ? ? ? ? ? +"abc"? ? ? ? ? ? ? ? +""? ? ? ? ? ? ? ? +"";? ? ? ??
pw.write(html);//寫內(nèi)容? ? ? ??
pw.close();//關閉流
基于需求分析的成果進行數(shù)據(jù)庫的設計,包含表熊咽,列以及關聯(lián)關系莫鸭,初始數(shù)據(jù)。
概要設計(開發(fā)框架的搭建横殴,核心技術的選擇)
首先被因,開發(fā)者需要對軟件系統(tǒng)進行概要設計,即系統(tǒng)設計衫仑。概要設計需要對軟件系統(tǒng)的設計進行考慮梨与,包括系統(tǒng)的基本處理流程、系統(tǒng)的組織結構文狱、模塊劃分粥鞋、功能分配、接口設計瞄崇、運行設計呻粹、數(shù)據(jù)結構設計和出錯處理設計等,為軟件的詳細設計提供基礎苏研。
詳細設計
(通過UML建模實現(xiàn) 類圖 時序圖)
在概要設計的基礎上尚猿,開發(fā)者需要進行軟件系統(tǒng)的詳細設計。在詳細設計中楣富,描述實現(xiàn)具體模塊所
涉及到的主要算法、數(shù)據(jù)結構伴榔、類的層次結構及調(diào)用關系纹蝴,需要說明軟件系統(tǒng)各個層次中的每一個
程序(每個模塊或子程序)的設計考慮,以便進行編碼和測試踪少。應當保證軟件的需求完全分配給整個
軟件塘安。詳細設計應當足夠詳細,能夠根據(jù)詳細設計報告進行編碼援奢。
編碼
在軟件編碼階段兼犯,開發(fā)者根據(jù)《軟件系統(tǒng)詳細設計報告》中對數(shù)據(jù)結構、算法分析和模塊實現(xiàn)等方面的設計要求,開始具體的編寫程序工作切黔,分別實現(xiàn)各模塊的功能砸脊,從而實現(xiàn)對目標系統(tǒng)的功能、
性能纬霞、接口凌埂、界面等方面的要求。在規(guī)范化的研發(fā)流程中诗芜,編碼工作在整個項目流程里最多不會
超過1/2瞳抓,通常在1/3的時間,所謂磨刀不誤砍柴功伏恐,設計過程完成的好孩哑,編碼效率就會極大提高
,編碼時不同模塊之間的進度協(xié)調(diào)和協(xié)作是最需要小心的翠桦,也許一個小模塊的問題就可能影響了
整體進度横蜒,讓很多程序員因此被迫停下工作等待,這種問題在很多研發(fā)過程中都出現(xiàn)過秤掌。
測試
測試編寫好的系統(tǒng)愁铺。交給用戶使用,用戶使用后一個一個的確認每個功能闻鉴。軟件測試有很多種:
按照測試執(zhí)行方茵乱,可以分為內(nèi)部測試和外部測試;按照測試范圍孟岛,可以分為模塊測試和整體聯(lián)調(diào)瓶竭;
按照測試條件,可以分為正常操作情況測試和異常情況測試渠羞;按照測試的輸入范圍斤贰,可以分為全
覆蓋測試和抽樣測試。以上都很好理解次询,不再解釋荧恍。總之屯吊,測試同樣是項目研發(fā)中一個相當重要
的步驟送巡,對于一個大型軟件,3個月到1年的外部測試都是正常的盒卸,因為永遠都會有不可預料的問
題存在骗爆。完成測試后,完成驗收并完成最后的一些幫助文檔蔽介,整體項目才算告一段落摘投,當然日后
少不了升級煮寡,修補等等工作,只要不是想通過一錘子買賣騙錢犀呼,就要不停的跟蹤軟件的運營狀況
并持續(xù)修補升級幸撕,直到這個軟件被徹底淘汰為止。
MD5字符串加密處理
MD5是一種不可逆的加密算法
網(wǎng)站一般會保存用戶密碼:
為了不讓數(shù)據(jù)庫管理員看到用戶的密碼圆凰。
比如你輸入的密碼明明是這樣的:123456
網(wǎng)站加密后的密碼可能是這樣的:E10ADC3949BA59ABBE56E057F20F883E
publicfinalstaticStringmd5(String s){charhexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};try{byte[] btInput = s.getBytes();? ? ? ? ? ? MessageDigest mdInst = MessageDigest.getInstance("MD5");? ? ? ? ? ? mdInst.update(btInput);byte[] md = mdInst.digest();intj = md.length;charstr[] =newchar[j *2];intk =0;for(inti =0; i < j; i++) {bytebyte0 = md[i];? ? ? ? ? ? ? ? str[k++] = hexDigits[byte0 >>>4&0xf];? ? ? ? ? ? ? ? str[k++] = hexDigits[byte0 &0xf];? ? ? ? ? ? }returnnewString(str);? ? ? ? }catch(Exception e) {? ? ? ? ? ? e.printStackTrace();returnnull;? ? ? ? }? ? }
常見錯誤:
404:服務器依據(jù)請求地址找不到相應的資源
1.沒有將項目部署到服務器 2.不一致 3.瀏覽器中請求地址有誤
500:系統(tǒng)出錯杈帐,程序在運行過程中出現(xiàn)問題
405:方法聲明錯誤
2.request的請求轉發(fā)和包含功能.
轉發(fā):
服務器接到客戶端的請求后,將請求轉發(fā)給WEB應用內(nèi)的其他資源處理
轉發(fā):request.getRequestDispatcher(“url”).forward(req,res);
url中的/可以寫专钉,也可以不寫挑童,建議寫。默認相對于項目名進行跳轉
3.request域的應用.
原理:
在request對象中含有一個map.這個map就是request域.
作用:
在將來開發(fā)中. 使用請求轉發(fā)時,servlet處理完數(shù)據(jù), 處理結果要交給jsp顯示. 可以使用request域將處理結果由servlet帶給jsp顯示.
操作:? ? 1.setAttribute存入一個鍵值對? ? 2.getAttribute通過鍵取出值? ? 3.getAttributeNames獲得域中所有鍵? ? 4.removeAttribute跟據(jù)鍵移除一個鍵值對request的范圍:? ? 一個request對象對應一個request域(map).? ? 系統(tǒng)當前有多少個request就有多少request域.
重定向
服務器接收到客戶端的請求之后跃须,返回給客戶端一個URL站叼,客戶端根據(jù)URL
重新發(fā)出HTTP請求
重定向:response.sendRedirect(“url”);
url:如果不以/開頭,表示相對于當前路徑進行跳轉(localhost:port/項目名/)
response.sendRedirect(“index.html”)
url:如果以/開頭菇民,表示相對于服務器域名進行跳轉(localhost:port/)
response.sendRedirect(request.getContextPath+“/index.html”)
圖片3.png
共同點:都是用來解決web組件(Servlet/JSP) 之間的跳轉問題
兩種方式的區(qū)別:
1.重定向支持項目資源外的跳轉(站外跳轉)尽楔,轉發(fā)只能站內(nèi)跳轉。
2.請求對象個數(shù):重定向2個 第练,轉發(fā)1個阔馋。
3.重定向后瀏覽器地址欄發(fā)生改變,轉發(fā)不變娇掏。
4.請求轉發(fā)性能好于重定向
至于選用哪種方式取決于數(shù)據(jù)共享的方式呕寝。如果采
用請求對象做數(shù)據(jù)的共享,則必須選用請求轉發(fā)的方式進行資源的跳轉婴梧。如果不選用請求對象做數(shù)據(jù)的共享下梢,都可以。
解決項目中不同的組件(Servlet)之間地跳轉(降低耦合度):
一個Servlet只去處理一個功能
使用規(guī)律:一般在增加塞蹭,修改孽江,刪除之后轉到查詢
661d.png
設計程序
注冊成功- - 跳轉到登陸頁面
登陸成功- - 跳轉到系統(tǒng)主頁
登陸失敗- - 重新回到 登陸頁面
完善12306項目的注冊功能以及登陸功能
JSP
用戶輸入錯誤的信息時,做出相應的提示番电。登錄到主頁時岗屏,顯示當前用戶的信息
對于這些信息需要在什么時候設置,就是在對一次請求做出響應時漱办,將相應的信息
傳遞到頁面當中
想要共享數(shù)據(jù)担汤,就需要在后臺進行數(shù)據(jù)的處理。需要將數(shù)據(jù)封裝起來洼冻,在網(wǎng)頁中來接受后臺封裝好的數(shù)據(jù)。對HTML來說隅很,它是一種靜態(tài)頁面撞牢,用來制作網(wǎng)頁率碾,顯示網(wǎng)頁內(nèi)容沒有問題,但是想要處理動態(tài)的數(shù)據(jù)時屋彪,用來訪問后臺傳遞的數(shù)據(jù)時所宰,是沒有這個功能的,需要用JSP來解決這個問題
什么是JSP: JSP:動態(tài)網(wǎng)頁技術畜挥。
如何編寫JSP:在WebContent下創(chuàng)建JSP文件 修改字符集仔粥,
Eclipse-window - preferences - 搜索 file -JSP files - utf-8 - apply -OK
JSP本質(zhì)是Servlet,瀏覽器與服務器連接后,服務器的通信組件會先找到JSP蟹但,tomcat將它翻譯成servlet(jsp->.java->.class)躯泰,初始化調(diào)用_jspInit(),_jspService(),_jspDestory()之后與servlet原理相同。
JSP的頁面元素
JSP腳本元素.png
1.網(wǎng)頁內(nèi)容华糖,HTML編寫
2.指令<%@? %> 用來設置JSP的數(shù)據(jù)項
Page:用于定義和頁面相關的屬性信息
Language=”java” JSP支持的腳本語言麦向,目前僅支持Java
ContentType:告訴瀏覽器輸出文本的格式及編碼
PageEncoding:設置文件的編碼,定義輸出流的字符集編碼客叉,默認iso-8859-1
Charset:設置文本內(nèi)容的字符集
Import=”java.util.*” 將指定的類引入到JSP上
JSP中page屬性可以寫多個诵竭,但建議每個page中的屬性只寫一次,import除外兼搏。
include指令:引入其他jsp
修改為了使項目默認部署到tomcat安裝目錄下的webapps中卵慰,show view—>servers—>找到需要修改的tomcat—>右擊
①停止eclipse內(nèi)的Tomcat服務器(stop)
②刪除該容器中部署的項目(add and remove)
③清除該容器相關數(shù)據(jù)(clean)
④打開tomcat的修改界面(open)
⑤找到servers location,選擇第二個(User tomcat Installation)
⑥修改deploy path為webapps
⑦保存關閉需要說明的是①②③必須操作佛呻,否則下面的步驟會被置灰無法操作裳朋。
3.嵌套java代碼,處理動態(tài)數(shù)據(jù)(腳本元素)
JSP表達式:<%=? %>
內(nèi)容編譯后成為變量件相, 表達式 再扭,有返回值的方法,會顯示結果
需要導入對應的java包import="java.util.Date"<%=newDate() %>
JSP腳本:? <%? %>
內(nèi)容編譯后成為寫在方法里的java代碼片段
<%for(inti=0;i<=5;i++){? ? }%>
JSP聲明:<%!? %>
內(nèi)容編譯后成為的成員變量(屬性)或成員方法
<%!inta;publicvoidshow(){? ? ? ? ? ? ? ? ? ? }? ? ? ? %>
腳本元素之間可以相互嵌套
<%!? ? ? ? publicvoidshow(){? ? %><%for(inti=0;i<=5;i++){%><%=i%><%}? ? ? ? %><%!}? ? %>
jsp和servlet的區(qū)別和聯(lián)系:
1.jsp經(jīng)編譯后就變成了Servlet.
(JSP的本質(zhì)就是Servlet夜矗,JVM只能識別java的類泛范,不能識別JSP的代碼,Web容器將JSP的代碼編譯成JVM能夠識別的java類)
2.jsp更擅長表現(xiàn)于頁面顯示,servlet更擅長于邏輯控制.
3.Servlet中沒有內(nèi)置對象,Jsp中的內(nèi)置對象都是必須通過HttpServletRequest對象紊撕,HttpServletResponse對象以及HttpServlet對象得到.Jsp是Servlet的一種簡化罢荡,使用Jsp只需要完成程序員需要輸出到客戶端的內(nèi)容,Jsp中的Java腳本如何鑲嵌到一個類中对扶,由Jsp容器完成区赵。而Servlet則是個完整的Java類,這個類的Service方法用于生成對客戶端的響應浪南。
JSP的9大內(nèi)置對象
JSP內(nèi)置對象.png
JSP如何處理后臺封裝的參數(shù)
Web層共享數(shù)據(jù)的范圍:
應用對象:ServletContext 整個Web項目都可以使用
會話對象:HttpSession 瀏覽器從打開到關閉笼才,就是一個會話。
請求對象:HttpServletRequest? 在一次請求中公用一個對象
頁面對象:PageContext? 在當前頁面中有效
原則:盡量使用范圍小的共享數(shù)據(jù)對象
利用request作數(shù)據(jù)共享:
request.setAttribute(數(shù)據(jù)名,數(shù)據(jù)值)? /? request.getAttribute(數(shù)據(jù)名)
session. setAttribute(數(shù)據(jù)名,數(shù)據(jù)值)? /? ? session. getAttribute(數(shù)據(jù)名)
在JSP頁面中獲取后臺傳遞的數(shù)據(jù)络凿,默認是Object,需要類型轉換
<%Stringerror=(String)request.getAttribute("error");%>用戶名<%if(error!=null){%><%=error%><%}? ? ? %>
用戶名
設計程序
登陸失敗 重新回到登陸頁面 在登陸頁中顯示錯誤提示
完成12306項目 登陸頁錯誤提示
會話對象HttpSession
指的是一段時間內(nèi)骡送,單個客戶端與服務器之間多次的交互過程
作用范圍:瀏覽器從打開到關閉昂羡,都可以使用
會話對象的作用
保證同一個客戶端,多次請求之間的聯(lián)系
創(chuàng)建HttpSession
HttpSession session=request.getSession();
session.setAttribute(key, value);
JSP中獲取Session
HttpSession sessions=request.getSession();sessions.getAttribute("")
設計程序
登陸成功后摔踱,在主要顯示當前用戶名
銷毀Session對象
session.invalidate();
設計程序
主頁中設計退出按鈕虐先,完成退出功能
正常情況 退出之后 跳轉到登陸頁
這里為了驗證是否退出成功,可以重新跳轉到主頁 查看用戶名是否存在
如果不存在 表示session對象已經(jīng)被銷毀 退出成功
完成12306項目 主頁退出功能
可以設計退出后重定向到主頁派敷,看是否存在用戶名
12306項目網(wǎng)頁用frame進行嵌套的蛹批,則無法使用轉發(fā)進行頁面跳轉
驗證碼
編寫驗證碼工具類publicfinalclassImageUtil{// 驗證碼字符集privatestaticfinalchar[] chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};// 字符數(shù)量privatestaticfinalintSIZE =4;// 干擾線數(shù)量privatestaticfinalintLINES =5;// 寬度privatestaticfinalintWIDTH =80;// 高度privatestaticfinalintHEIGHT =40;// 字體大小privatestaticfinalintFONT_SIZE =30;/**
? ? * 生成隨機驗證碼及圖片
? ? */publicstaticObject[] createImage() {? ? ? ? StringBuffer sb =newStringBuffer();// 1.創(chuàng)建空白圖片BufferedImage image =newBufferedImage(? ? ? ? ? ? WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);// 2.獲取圖片畫筆Graphics graphic = image.getGraphics();// 3.設置畫筆顏色graphic.setColor(Color.LIGHT_GRAY);// 4.繪制矩形背景graphic.fillRect(0,0, WIDTH, HEIGHT);// 5.畫隨機字符Random ran =newRandom();for(inti =0; i
? ? * 隨機取色
? ? */publicstaticColorgetRandomColor(){? ? ? ? Random ran =newRandom();? ? ? ? Color color =newColor(ran.nextInt(256),? ? ? ? ? ? ? ? ran.nextInt(256), ran.nextInt(256));returncolor;? ? }? ? }
Servlet中獲取驗證碼// 生成驗證碼圖片Object[] objs = ImageUtil.createImage();// 將驗證碼存入sessionStringimgcode = (String) objs[0];? ? ? ? ? ? ? ? request.getSession().setAttribute("imgcode", imgcode);// 將圖片輸出給瀏覽器BufferedImage img = (BufferedImage) objs[1];? ? ? ? ? ? ? ? response.setContentType("image/png");// tomcat自動創(chuàng)建輸出流// 目標就是本次訪問的瀏覽器OutputStream os = response.getOutputStream();? ? ? ? ? ? ? ? ImageIO.write(img,"png", os);? ? ? ? ? ? ? ? os.close();
客戶端調(diào)用驗證碼
? onclick="this.setAttribute('src','Servlet映射路徑?x='+Math.random())"/>
會話對象Cookie
HTTP是無狀態(tài)協(xié)議,服務器無法記住瀏覽器篮愉,cookie和session能夠對狀態(tài)進行管理腐芍,讓服務器記住瀏覽器。
狀態(tài):用來證明瀏覽器來過服務器的表示數(shù)據(jù)
Cookie是在客戶端保存信息的技術
Cookie 是一小段文本信息潜支,伴隨著用戶請求和頁面在 Web 服務器和瀏覽器之間傳遞甸赃。用戶每次訪問站點時,Web 應用程序都可以讀取 Cookie 包含的信息冗酿。
cookie原理.
讓瀏覽器記住鍵值對.是向響應頭中添加一下頭即可:
set-Cookie:name=tom;
瀏覽器記住之后,向服務器發(fā)送鍵值對,是在請求頭中添加下面的信息:
Cookie: name=tom;
創(chuàng)建 Cookie
創(chuàng)建Cookie對象 設置存儲的內(nèi)容Cookie cookie=newCookie("username","chen");設定cookie的保存時長埠对,單位 秒cookie.setMaxAge(60*60*5);將cookie添加到response對象中response.addCookie(cookie);
cookie細節(jié)問題:
1.瀏覽器記多久?
默認是在會話期間有效.(關閉瀏覽器,cookie就被刪除).(有效時間-1)
2.有效時間如何設置?
//設置cookie的最大有效時間
1>設置一個正數(shù),標示最大有效時間.單位是秒
//cookie.setMaxAge(60*60);
2>設置為-1 , 就是相當于默認有效時間, 瀏覽器關閉就消失.
//cookie.setMaxAge(-1);
3> 標示cookie的有效時間為0.發(fā)送到瀏覽器就消失了.
JSP中獲取Cookie
<%Stringname="";? ? Cookie[] cookies=request.getCookies();/* 通過cookie中的key 獲取需要的cookie元素? ? */for(Cookie cookie:cookies){if(cookie.getValue().equals("chen")){? ? ? ? ? ? name=cookie.getValue();? ? ? ? }? ? }%>
Cookie的原理
圖片6.png
Cookie的特點:
存儲在瀏覽器端,隱私性差裁替,安全性較低项玛。
保存在本地磁盤中,臨時存儲弱判。
用于數(shù)據(jù)的傳遞
設計程序
登陸成功的用戶襟沮,關閉瀏覽器后。下一次打開瀏覽器時
登陸頁自動顯示用戶名和密碼
解決自動登錄問題:Cookie
圖片5.png
當用戶訪問到一在創(chuàng)建這個SESSION的時候昌腰,服務器首先檢查這個用戶發(fā)來的請求里是否包含了一個SESSION ID开伏,如果包含了一個SESSION ID則說明之前該用戶已經(jīng)登陸過并為此用戶創(chuàng)建過SESSION,那服務器就按照這個SESSION ID把這個SESSION在服務器的內(nèi)存中查找出來(如果查找不到遭商,就有可個服務器固灵,如果服務器啟用Session,服務器就要為該用戶創(chuàng)建一個SESSION劫流,能為他新創(chuàng)建一個)巫玻,如果客戶端請求里不包含有SESSION ID,則為該客戶端創(chuàng)建一個SESSION并生成一個與此SESSION相關的SESSION ID祠汇。這個SESSION ID是唯一的仍秤、不重復的、不容易找到規(guī)律的字符串可很,這個SESSION ID將被在本次響應中返回到客戶端保存诗力,而保存這個SESSION ID的正是COOKIE,這樣在交互過程中瀏覽器可以自動的按照規(guī)則把這個標識發(fā)送給服務器我抠。
3.原理
瀏覽器第一次訪問服務器,服務器會在內(nèi)存中開辟一個空間(session),并把session對應的ID發(fā)送給瀏覽器.
那么下次瀏覽器再去訪問服務器,會把sessionID 交給服務器,服務器通過sessionID 找到剛才開辟的空間.
以上就是session的原理.
4.session細節(jié)問題
1> 服務器讓瀏覽器記住sessionID的cookie 默認過期時間是 (-1)==> 關閉瀏覽器 cookie就丟失 ==>? cookie丟失 sessionID就丟失 ==> 找不到服務器的session
2> session中除了 4個操作 map的方法之外,還有哪些方法.
long getCreationTime()? 獲得創(chuàng)建時間
String getId()? ? 獲得sessionID
long getLastAccessedTime()? 獲得最后一次訪問時間
int? getMaxInactiveInterval()? 獲得session的壽命
void setMaxInactiveInterval(int interval)? 設置session的過期時間
void invalidate()? 讓session立即失效
boolean isNew()
3> 關于設置session的最大有效時間
默認是30分鐘. ==> 在tomcat的web.xml中 配置的.
如何修改session的過期時間?
1.修改在tomcat的web.xml中 ==> 影響服務器中的所有項目
2.在項目的web.xml中 加入 配置.==> 影響的是當前項目
3.通過setMaxInactiveInterval(int interval)方法設置.==> 當前操作的session
4>(了解內(nèi)容)URL重寫
? ? 如果瀏覽器 禁用cookie功能不能保存任何cookie.那么session技術要是用 cookie來保存sessionID. 沒有cookie怎么保存?
? ? ? ? 使用url重寫解決該問題.
? ? ? ? 將頁面中所有的連接 末尾全都加上 cookieid的參數(shù). 這樣用戶點擊連接訪問網(wǎng)站,通過url把SeesionID帶到了服務器.這樣就解決了.
? ? ? ? 但是 互聯(lián)網(wǎng)行業(yè)沒有這么干的.
當用戶長時間沒有做出任何指令和動作時姜骡,自動退出导坟。
解決方式:修改session的超時時間,默認30分鐘圈澈。當服務器(tomcat)檢查到用戶超過這個時間沒有任何動作時,將session銷毀尘惧。從session不活動的時候開始計算康栈,如果session一直活動,session就總不會過期喷橙。從該Session未被訪問,開始計時; 一旦Session被訪問,計時清0;在web.xml配置
EL表達式:代替JSP中的JAVA代碼啥么,作為動態(tài)數(shù)據(jù)的輸出。
JSP表達式如果為空值時贰逾,會報空指針異常悬荣,在代碼上需要做判斷處理
而EL表達式則不會有這樣的問題
語法:${表達式}
可以訪問req和res中的數(shù)據(jù),可以訪問cookie和其他請求報文中的信息
EL表達式默認從4個內(nèi)置對象中取值疙剑,并且是依次取值氯迂。(page,request ,session,appliction)
從小的作用域開始查找對應的數(shù)據(jù)對象,找到為止。
在實際開發(fā)中闷沥,不同的作用域不建議起相同的數(shù)據(jù)名
Cookie不是EL的內(nèi)置對象龄捡,取值 ${cookie.參數(shù)名.value}
練習:用EL表達式獲取bean(實體類)中的屬性和方法 ${user.username}
數(shù)據(jù)庫連接池
數(shù)據(jù)庫連接的建立和資源的關閉都是消耗巨大的
每次操作數(shù)據(jù)庫都要打開,關閉物理連接累魔,系統(tǒng)的性能嚴重受損
解決方案:
系統(tǒng)初始運行的時候,主動建立足夠的連接,組成一個連接池导帝。
每次程序請求數(shù)據(jù)庫連接時,無需重新打開數(shù)據(jù)庫連接穿铆,而是從連接池
中獲取已有的連接您单。使用完后,不再關閉悴务,而是歸還給連接池睹限。
privatestaticBasicDataSource ds;// 數(shù)據(jù)庫連接池static{? ? ? ? ? ? ds =newBasicDataSource();? ? ? ? ? ? ds.setDriverClassName("com.mysql.jdbc.Driver");// Class.forName(...)ds.setUrl("jdbc:mysql://localhost:3306/mysql");? ? ? ? ? ? ds.setUsername("root");? ? ? ? ? ? ds.setPassword("root");? ? ? ? ? ? ds.setInitialSize(5);? ? ? ? ? ? System.out.println(ds.getInitialSize());? ? }/**
? ? * 獲取數(shù)據(jù)庫連接
? ? */publicstaticConnectiongetConnection()throws Exception{returnds.getConnection();? ? }publicstaticvoidcloseConnection(Connection conn){try{? ? ? ? ? ? conn.close();? ? ? ? }catch(SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();? ? ? ? }? ? }
功能顯示查詢數(shù)據(jù) (組合查詢)
由于查詢的條件不同,所有顯示的數(shù)據(jù)也會有所不同(內(nèi)容和數(shù)量)
HTML本身的標簽無法實現(xiàn)讯檐,需要使用自定義標簽JSTL
jstl.jar在jsp中通過taglib指令引入羡疗,才可以使用.<%@? taglib? uri=”” prefix=””? %>
uri:是自定義標簽庫的地址? prefix:標簽庫的別名
jstl.png
循環(huán)遍歷
foreach.png
分頁查詢
復合查詢.png
刪除功能
ServletConfig對象是什么?
封裝了servlet在web.xml中的配置.
方法:
1>getServletName ==> 獲得配置文件中 元素的內(nèi)容
2>getInitParameter ==> 根據(jù) 中的 獲得
name
tom
3>getInitParameterNames 返回所有 .
HTTPServlet:
1.因為我們web項目基于HTTP協(xié)議,所以Service方法中傳過來的request,response對象都是 基于HTTP協(xié)議的.
也就是HttpServletReueqst,也就是HttpServletResponse. 它幫我們進行了強轉.
2.我們有可能在不同的請求方式時做不同的事情. 根據(jù)請求方式不同,調(diào)用不同的方法
例如 GET --> doGet()
POST ==> doPost();
相關對象之 ---- ServletContext
1.獲得: servletConfig ==> getServletContext
2.servletContext 的作用
1> servletContext 封裝了web.xml 中的配置
name
jerry
password
1234
getInitParameterNames();? ==> 獲得所有鍵? ? ? ? ? ? ? ? getInitParameter(key);? ==> 根據(jù)鍵獲得對應的值2> servlet技術中3大域對象之一.? ? ? ? ServletContext對應著Application(應用)域.利用了一個項目中只有一個ServletContext實例的特點.在servletContext中放置了一個map用作數(shù)據(jù)通信.? ? ? ? 這個Map就是所謂域.? ? ? ? ? ? 關于域的操作,有4個.? ? ? ? ? ? ? ? 放入鍵值對 setAttribute(key,value)? ? ? ? ? ? ? ? 通過鍵取值 getAttribute(key)? ? ? ? ? ? ? ? 通過鍵刪除 removeAttribute(key)? ? ? ? ? ? ? ? 遍歷所有鍵 getAttributeNames()? ? ? ? ? ? application ==> servletContext? ? ? ? ? ? session ==>? ? ? ? ? ? request ==>3>獲得項目中資源.? ? ? ? ? 所有servletContext中關于路徑的獲得,相對路徑都是相對的 WebRoot(項目根)下? ? ? ? ? ? getRealPath? ==> 通過相對路徑獲得絕對路徑? ? ? ? ? ? getResourceAsStream ==> 根據(jù)相對路徑獲得指定資源流3.servlet技術中對象的范圍? ? servlet ==> 項目啟動期間一個servlet只有一個servlet實例? ? request ==> 項目啟動期間,request對象的數(shù)量,要看當前有多少個請求正在處理.? ? response ==> 同上.? ? servletConfig ==> 一個servlet實例對應一個servletConfig對象? ? servletContext ==> 整個項目中,永遠只有一個servletContext實例存在
在web.xml中配置錯誤頁面攔截(報錯后跳轉到錯誤頁面)
正常情況系統(tǒng)不應該將報錯的頁面顯示給用戶,或者說不應該讓用戶看到别洪。對于一些懂技術的人來說叨恨,看到報錯信息,可能會找到系統(tǒng)的漏洞挖垛,造成不必要的麻煩痒钝。
解決:系統(tǒng)報錯時秉颗,根據(jù)錯誤類型,跳轉到相應的頁面
通過配置web.xml文件送矩,讓tomcat統(tǒng)一處理異常蚕甥,即告訴tomcat在發(fā)生異常時,轉發(fā)到什么錯誤頁面
1.通過異常類型聲明
java.langException
錯誤網(wǎng)頁的url
2.通過錯誤編碼聲明(405栋荸,500寫法相同)
404< /error-code>
錯誤網(wǎng)頁的url
由于任何地方都可能報錯菇怀,所以無法確定相對路徑,所以JSP訪問路徑應該為絕對路徑
并且該路徑不能寫項目名晌块,tomcat會自動補充爱沟。
過濾器
解決項目中的一些共性需求,如日志匆背,過濾敏感詞呼伸,登錄檢查等。
創(chuàng)建一個過濾器:該類實現(xiàn)了Filter接口钝尸,重寫了三個方法 init(),destroy(),doFilter()
init() 初始化方法,destroy( ) 銷毀方法 括享,通常不寫內(nèi)容
doFilter():在tomcat啟動時,會自動調(diào)用該方法蝶怔,傳入ServletRequest,ServletResponse
由于需要獲取session和servlet中的訪問路徑奶浦,需要對參數(shù)進行強轉為HttpServletRequest
HttpServletResponse
配置webxml
/*
過濾器原理:
1.通過過濾器統(tǒng)一解決亂碼問題
在過濾器的doFilter方法中設置編碼的轉換,在執(zhí)行chain.doFilter(request, response);之前
將編碼設置成utf-8
chain.doFilter(request, response);表示將請求交給下一個Filter或者Servlet處理
如果不調(diào)用該方法則請求結束踢星。
2.通過Filter進行系統(tǒng)校驗澳叉,用戶只能通過登錄頁面進入系統(tǒng)
設置了過濾器之后,所有的請求都會被攔截沐悦,也就是登錄的請求也會被攔截
那么就需要將該請求排除攔截的范圍成洗。其他的請求不變。
登錄的用戶會把信息保存在session中藏否,若sesion中沒有數(shù)據(jù) 則該用戶沒有登錄瓶殃,進行攔截
跳轉到登錄頁面。
FileUpload實現(xiàn)文件上傳
boolean isMultipart = ServletFileUpload.isMultipartContent(request);? ? ? ? System.out.println(isMultipart);//1副签、創(chuàng)建一個DiskFileItemFactory工廠DiskFileItemFactory factory =newDiskFileItemFactory();//2遥椿、創(chuàng)建一個文件上傳解析器ServletFileUpload upload =newServletFileUpload(factory);//解決上傳文件名的中文亂碼upload.setHeaderEncoding("UTF-8");? ? ? ? upload.setSizeMax(1024*1024*5);//設置上傳的文件總的大小不能超過5Mtry{//解析請求對象List fileList= upload.parseRequest(request);//遍歷請求結果Iterator iter = fileList.iterator();while(iter.hasNext()){? ? ? ? ? ? ? ? FileItem item = iter.next();//判斷當前遍歷到的元素是否為普通的表單if(item.isFormField()){Stringname =newString(item.getFieldName().getBytes("iso8859-1"),"utf-8");Stringvalue =newString(item.getString().getBytes("iso8859-1"),"utf-8");? ? ? ? ? ? ? ? ? ? System.out.println(name);? ? ? ? ? ? ? ? ? ? System.out.println(value);? ? ? ? ? ? ? ? }else{//圖片的上傳//獲取文件名StringfileName = item.getName();? ? ? ? ? ? ? ? ? ? System.out.println(fileName);//重命名StringnewFileName =newDate().getTime()+fileName.substring(fileName.indexOf('.'));//構建File對象System.out.println(getServletContext().getRealPath("/images/photo"));? ? ? ? ? ? ? ? ? ? File file =newFile( getServletContext().getRealPath("/images/photo"),newFileName);? ? ? ? ? ? ? ? ? ? item.write(file);? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? }catch(FileUploadException e) {// TODO Auto-generated catch blocke.printStackTrace();? ? ? ? }catch(Exception e) {// TODO Auto-generated catch blocke.printStackTrace();? ? ? ? }? ? }
文件上傳的問題
上傳的圖片保存在tomcat下的webapps中,并不是本地的項目空間淆储。如果平時測試代碼時需要重新部署項目冠场,這將導致webapps下的項目被項目空間的所替換,之前上傳到服務器中的文件也就消失了本砰。
測試臨時解決辦法:將文件上傳路徑碴裙,設置為項目空間
歸根到底這些問題其實還是因為我們是在調(diào)試的工程中,發(fā)布后肯定是不會出現(xiàn)這些問題的。發(fā)布了之后你的tomcat服務器只有關閉和打開舔株,而不會對工程重新部署莺琳,自然也就不會出現(xiàn)這些問題
上傳圖片文件(圖像)時如何立即顯示
//判斷瀏覽器是否支持FileReader接口if(typeofFileReader =='undefined') {? ? alert("
當前瀏覽器不支持FileReader接口
");? }//選擇圖片,馬上預覽functionxmTanUploadImg(obj){varfile = obj.files[0];varreader =newFileReader();? ? reader.onload =function(e){varimg =document.getElementById("img1");console.log(e.target.result);//Date url格式img.src = e.target.result;? ? }? ? reader.readAsDataURL(file);? }
Ajax是一種用來改善用戶體驗的技術载慈。其實質(zhì)是利用瀏覽器提供的ajax對象(XMLHttpRequest) 異步的向服務器發(fā)送請求惭等,服務器響返回數(shù)據(jù),瀏覽器利用這些數(shù)據(jù)進行頁面的局部更新
整個過程办铡,頁面無刷新效果咕缎,不打斷用戶的操作。
異步:指的是當ajax對象發(fā)送請求時料扰,瀏覽器不會銷毀當前頁面
提交表單請求時,會銷毀當前頁面(刷新)
獲取ajax對象functiongetXhr(){varxhr;if(window.XMLHttpRequest){? ? ? ? 非IE? ? xhr=newXMLHttpRequest();? ? }else{? ? ? ? ? IE瀏覽器下獲取方式? ? ? ? xhr=newActiveXObject("Microsoft.XMLHttp");? ? }returnxhr;}觸發(fā)ajax的事件函數(shù)onreadystatechange:綁定事件的處理函數(shù)當readyState屬性值發(fā)生改變時焙蹭,會觸發(fā)readystatechange事件readyState:有5個值(0晒杈,1,2孔厉,3拯钻,4),表示ajax對象與服務器的通信進度? ? ? ? ? ? 當值為4的時候撰豺,表示已經(jīng)獲得了服務器返回的數(shù)據(jù)status:表示服務器返回的狀態(tài)碼200表示成功responseText:表示服務器返回的文本數(shù)據(jù)xhr.send():將請求發(fā)送給服務器粪般,必須寫functionsendHttpReq(){? ? 獲取ajax對象varxhr=getXhr();? ? ? 通過ajax向服務器發(fā)送請求? ? xhr.open("get","servlet映射路徑",true);? ? xhr.onreadystatechange=function(){if(xhr.readyState==4&&xhr.status==200){varmsg=xhr.responseText;? ? ? ? }? ? };? ? ? ? xhr.send();}
服務器相應ajax PrintWriter pw= response.getWriter(); pw.print(響應信息); pw.close();