Java web筆記
Web應(yīng)用的部署方式:
1、直接把要部署的工程的web-root拷貝到tomcat的webapps文件下。a)通常采用集成開發(fā)工具進(jìn)行部署。2、采用虛路徑(邏輯路徑)的方式部署。
a)在tomcat的server.xml文件的host標(biāo)簽下加入如下標(biāo)簽:
b)其中path表示應(yīng)用的context-rootDocbase表示應(yīng)用程序的實(shí)際路徑。
Context-root:
是web應(yīng)用程序中URI的第一級路徑。
練習(xí):編寫一個(gè)index.html文件,然后在index.html中添加超鏈接,連接到hello.html.
配置web應(yīng)用的歡迎界面
當(dāng)用戶請求的URI地址與context-root匹配時(shí),web應(yīng)用會(huì)轉(zhuǎn)到歡迎界面。歡迎界面的配置,配置到web.xml中的welcome-file-list標(biāo)簽。
Servelt的使用。
一、新建一個(gè)類,該類繼承httpservlet
二、重寫該類中的doget或dopost方法,用來處理用戶的get請求或者post請求。三、在web.xml中配置servlet,分別配置如下標(biāo)簽
a)1.:表示的是servlet的邏輯名
2.:表示的是servlet的實(shí)際路徑名。
b)1.:表示的是servlet的邏輯名
2.:表示的是servlet截獲什么樣的請求。發(fā)請求的方式:
Get方式:直接在地址欄中輸入U(xiǎn)RL,敲回車
中的method不寫,或者method=”get”POST:中的method=”post”
Servelt:
概念:servlet是一個(gè)與平臺(tái)無關(guān)的服務(wù)器組件,它的運(yùn)行,方法調(diào)用、實(shí)例化、初始化、銷毀都是由容器來完成的。Servelt主要負(fù)責(zé)處理客戶端發(fā)送過來的請求,并給客戶端做出響應(yīng)。API:javax.servlet,javax.servelt.httpHTTP協(xié)議:請求與響應(yīng)對象請求中的參數(shù)格式
URI?參數(shù)名=參數(shù)值&參數(shù)名=參數(shù)值
練習(xí):做一個(gè)登錄界面,在頁面上輸入用戶名和密碼,點(diǎn)提交,使用servlet來截獲用去的請求,當(dāng)用戶輸入的用戶名和密碼為admin時(shí),在成功頁面顯示歡迎您XXXX,登錄成功,否則顯示對不起XXX,登錄失敗。
Get和Post請求方式的差異:
1、傳送數(shù)據(jù)的大小,get方式較小,post較大。2、是否安全:get相對不安全,post相對安全
3、是否改變服務(wù)器的狀態(tài):get不改變,post改變。
4、是否是默認(rèn)方式的請求:get是默認(rèn)的,post不是默認(rèn)的。
注意:在實(shí)際編寫程序時(shí),盡量使用post方式發(fā)送請求。
練習(xí):做一個(gè)注冊界面,在頁面放置各種不同的元素,在請求對象中讀取參數(shù)值,并顯示在頁面上。用戶名:文本框
密碼:密碼框
性別:單選框(男,女)
愛好:復(fù)選框(游泳,足球,下棋,唱歌)用戶編號:hidden個(gè)人簡歷:文本域
籍貫:下拉框.(遼寧、吉林、山東、河北)提交按鈕、重置按鈕路徑問題
當(dāng)前服務(wù)器路徑::8088/,也就是URL的前兩部分。
當(dāng)前應(yīng)用路徑::8088/context-root,也就是URL的全部。
在FORM標(biāo)簽中:
如果action的路徑是以/開頭,那么表示請求是發(fā)送到“當(dāng)前服務(wù)器路徑”+action的值。
如果action的路徑不以/開頭,那么表示請求是從當(dāng)前的URL開始發(fā)送,也就是當(dāng)前的URL+action的值。
如果以./開頭,也表示從當(dāng)前的URL開始發(fā)送。
如果以../開頭,表示從當(dāng)前的URL向上退一級+action的值。
當(dāng)使用超鏈接提交請求時(shí),必須自己構(gòu)造URL,如:Login
注意:中的路徑問題和Form的action屬性,所表示的含義是一樣的。
如果href的路徑是以/開頭,那么表示請求是從“當(dāng)前服務(wù)器路徑”開始發(fā)送。
如果href的路徑不以/開頭,那么表示請求是從當(dāng)前的URL開始發(fā)送。如果href的路徑以./開頭,也表示從當(dāng)前的URL開始發(fā)送。如果href的路徑以../開頭,表示從當(dāng)前的URL向上退一級。
Servlet對象的生存周期
1、加載
2、實(shí)例化,調(diào)用構(gòu)造器3、初始化,int4、處理請求,service5、銷毀:destroy
load-on-startup選項(xiàng):
1、在服務(wù)器啟動(dòng)的時(shí)候執(zhí)行servlet的實(shí)例化及初始化工作。
2、此Servlet在整個(gè)web應(yīng)用中裝載的次序。數(shù)值越小,越先裝載。(通常是應(yīng)用程序中有多個(gè)servlet的時(shí)候,servelt之間有相互調(diào)用,可以用此選項(xiàng)決定servlet的加載順序)
servlet配置的參數(shù):
1.配置:在web.xml中的servlet標(biāo)簽下配置子標(biāo)簽
2.讀。涸趕ervlet中調(diào)用this.getServletConfig.getInitParamter(String
name)JSP的生命周期
1、jsp翻譯成Servlet源碼2、編譯成字節(jié)碼文件3、加載
4、實(shí)例化:調(diào)用構(gòu)造器5、初始化:調(diào)用jspInit6、處理請求:調(diào)用jspservice7、銷毀:調(diào)用jspDestroy
Jsp第一次運(yùn)行較慢的原因:因?yàn)榈谝淮芜\(yùn)行是要進(jìn)行翻譯和編譯的。以后就直接從第三步開始了。
JPS中的靜態(tài)HTML代碼處理
寫法:直接和在.html中一樣處理:直接寫到輸出流中。
JSP腳本元素的處理
一、ScriptLet:定義java代碼
a)寫法:
b)處理:直接被翻譯到j(luò)spservice方法中二、Jsp表達(dá)式:在頁面輸出。
a)寫法:
b)處理:被翻譯到j(luò)spservice方法中輸出流中
練習(xí):做一個(gè)登錄頁面,請求有jsp來處理,當(dāng)用戶和密碼都為admin時(shí),顯示welcome,xxx,否則顯示sorry,xxx
三、JSP聲明:定義一些變量及方法。
a)寫法:
b)處理:被翻譯成jsp的成員變量和成員方法四、Jsp注釋:
a)寫法:
b)處理:在翻譯的時(shí)候被忽略掉。五、HTML注釋:
a)寫法:
b)處理:被翻譯到輸出流中,客戶端解析的時(shí)候忽略掉。六、Java注釋:
a)寫法:
b)處理:直接被翻譯成jspService方法中的java注釋。
練習(xí):
1、自己寫一個(gè)jsp文件,在其中包含jsp聲明及注釋,注意這些腳本元素的處理。
2、定義一個(gè)jsp文件,使用Jsp腳本元素,在頁面上循環(huán)輸出10行記錄,每個(gè)記錄包含兩列,列名分別為姓名,年齡,數(shù)據(jù)如下:
序號12345678910姓名張三1張三2張三3張三4張三5張三6張三7張三8張三9張三10年齡21222324252627282930JSP中隱式對象(預(yù)定義變量)
事先被聲明并且初始化好的對象。HttpServletRequest
二、response:表示一個(gè)響應(yīng)對象,里面封裝著對用戶的相應(yīng)信息,由容器創(chuàng)建,類型為:
HtttpServletResponse。三、session:表示一個(gè)用戶和系統(tǒng)的一系列交互,里面包含很多request,由容器創(chuàng)建,類型
類:HttSession
練習(xí):自己練習(xí)reqeust、response、session對象的使用。a)當(dāng)重新開啟一個(gè)瀏覽器時(shí),是一個(gè)新的session對象。
b)當(dāng)通過開始-新建一個(gè)瀏覽器窗口時(shí),保持原有的session對象。
四、application:表示一個(gè)web應(yīng)用,里面可以封裝整個(gè)web應(yīng)用都能使用的屬性,由容器
創(chuàng)建,類型為:ServletContext五、pageContext:表示當(dāng)前頁面的對象,里面可以封裝只能本頁面使用的一些屬性,由容器
創(chuàng)建,類型為:PageContext練習(xí):
1、做一個(gè)jsp,分別向pageContext,request,session,application四個(gè)對象中放置一個(gè)屬性,屬性名為a1,屬性值不同,然后再從4個(gè)對象中分別取出屬性a1,觀察結(jié)果。
2、做三個(gè)jsp,分別a.jsp,b.jsp,c.jspa頁面上連接到b,b上連接到c,在a頁面上分別向
pageContext,request,session,application四個(gè)對象中放置一個(gè)屬性,屬性名分別為h1,h2,h3,h4,屬性值為一個(gè)包含10個(gè)String對象的List,在b頁面和c頁面分別從4個(gè)對象取出這個(gè)list,觀察結(jié)果。
一、request:表示一個(gè)請求對象,里面封裝著用戶的請求信息,由容器創(chuàng)建,類型為:
擴(kuò)展閱讀:java web筆記大全
收集整理
javaweb筆記大全
Lesson1
一、eclipse工具的使用
1.java代碼的位置
1)選擇工作空間workspace選擇一個(gè)文件夾存放程序(代碼)不要用中文和空格2)新建一個(gè)java工程(Project)
3)建包建類
2.快捷鍵
alt+/:代碼自動(dòng)補(bǔ)齊,需要配置的打開preferences(首選項(xiàng)),搜keys,打開快捷鍵配置面板搜a(bǔ)lt+/,取消綁定搜contentassist,取消原先的綁定,配置成alt+/
ctrl+1:錯(cuò)誤自動(dòng)修復(fù),注意,放行的紅叉是可修復(fù)的,圓形的是不可修復(fù)的導(dǎo)包的三種方式:
1)將類名敲完整,按下alt+/進(jìn)行補(bǔ)齊,會(huì)自動(dòng)導(dǎo)包2)ctrl+1,修正錯(cuò)誤
3)ctrl+shift+o整理包,導(dǎo)入需要的包,去掉多余的導(dǎo)包語句ctrl+shift+f:代碼格式化ctrl+2,L自動(dòng)聲明變量
shift+enter光標(biāo)直接進(jìn)入下一行ctrl+alt+方向鍵(向上向下)復(fù)制行alt+方向鍵(向上向下)移動(dòng)當(dāng)前行
3.斷點(diǎn)調(diào)試
1)可以對程序進(jìn)行調(diào)試
在行的開頭雙擊左鍵打斷點(diǎn),用debug方式來運(yùn)行程序,程序就會(huì)停留在斷點(diǎn)位置
F5跳入(stepinto)跳入方法內(nèi)部F6跳過,讓當(dāng)前行運(yùn)行F7跳出返回上一層程序resume直接運(yùn)行到下一個(gè)斷點(diǎn)
2)查看源代碼建議使用斷點(diǎn)調(diào)試的方式,注意當(dāng)前運(yùn)行環(huán)境需要包含源碼
4.junit單元測試
1)寫一個(gè)java類,聲明測試方式修飾符為publicvoid,在方法前面加注解,(@Test)此方法就可以進(jìn)行測試了(交給junit運(yùn)行)2)需要在測試方法前做初始化工作
寫一個(gè)靜態(tài)方法publicstaticvoidinit()
在方法前加注解@BeforeClass
收集整理
3)需要在測試后釋放資源寫一個(gè)靜態(tài)方法在方法前加注解@AfterClass
二、jdk5新特性
1.靜態(tài)導(dǎo)入
1)導(dǎo)入類的靜態(tài)屬性importstaticjava.lang.System.out;out.println("haha");2)導(dǎo)入類的靜態(tài)方法importstaticjava.lang.Math.*;//導(dǎo)入Math類的所有靜態(tài)成員intnum=abs(-10);2.增強(qiáng)for循環(huán)
1)作用:對存儲(chǔ)對象的容器進(jìn)行迭代2)jdk5以前怎么迭代3)增強(qiáng)for循環(huán)迭代數(shù)組
String[]arr={"a","b","c"};//傳統(tǒng)方式for(inti=0;iIntegerbyte-->Byteshort-->Shortlong-->Longchar-->Characterdouble-->Double
收集整理
float-->Float
boolean-->Boolean
1)Integerx=1;x=x+1;經(jīng)歷了什么過程?裝箱拆箱裝箱
2)為了優(yōu)化,虛擬機(jī)為包裝類提供了緩沖池,Integer池的大小-128~127一個(gè)字節(jié)的大小3)String池Java為了優(yōu)化字符串操作提供了一個(gè)緩沖池面試題:Strings=“abc”和Strings=newString(“abc”)的區(qū)別Strings=newString(“abc”)創(chuàng)建了幾個(gè)對象Strings=“a”+“b”+“c”+“d”創(chuàng)建了幾個(gè)對象Strings1=“a”Strings2=“b”Strings3=s1+s2;s3==”ab”?/*1.Strings="abc",虛擬機(jī)首先會(huì)檢查String池里有沒有"abc"對象(通過equals方法)
//如果有,直接返回引用,如果沒有,會(huì)在池里創(chuàng)建一個(gè)“abc”對象,并返回引用Strings1="abc";Strings2="abc";System.out.println(s1==s2);//result:true*//*2.Stringstr=newString("abc");//此時(shí),負(fù)責(zé)檢查并維護(hù)緩沖池,其實(shí)堆內(nèi)存的對象是緩沖池中"abc"對象的一個(gè)拷貝Strings1=newString("abc");Strings2=newString("abc");System.out.println(s1==s2);//result:false*//*3.Strings="a"+"b"+"c"+"d";java編譯器有個(gè)合并已知量的優(yōu)化功能//在編譯階段就把"a"+"b"+"c"+"d"合并為”abcd“Strings="a"+"b"+"c"+"d";System.out.println(s=="abcd");//result:true*//*4.Strings1="a";Strings2="b";Strings3=s1+s2;//String是常量,不能相加的,java如何實(shí)現(xiàn)的?StringBuildersb=newStringBuidler(s1);sb.append(s2);s3=sb.toString();也就是說實(shí)際上s3是方法返回的String對象凡是方法返回的字符串對象都是在堆內(nèi)存的*/Strings1="a";Strings2="b";3
不管緩沖池是否有"abc",都會(huì)在堆內(nèi)存創(chuàng)建一個(gè)"abc"對象,返回引用//Strings="abcd";收集整理Strings3=s1+s2;//堆內(nèi)存的對象System.out.println(s3=="ab");//result:false4)單列集合Collection
Listlist=newArrayList();list.add("aaa");list.add("bbb");list.add("ccc");//傳統(tǒng)方式1/*1.獲得迭代器Iteratoriter=list.iterator();//2.循環(huán)判斷迭代器是否有下一個(gè)while(iter.hasNext()){}*///傳統(tǒng)方式2for(Iteratoriter=list.iterator();iter.hasNext();){}System.out.println("--------------------------------");//增強(qiáng)for循環(huán),沒有使用泛型的集合能不能使用增強(qiáng)for循環(huán)迭代?能for(Objectobj:list){}Strings=(String)obj;System.out.println(s);Strings=(String)iter.next();System.out.println(s);Stringstr=(String)iter.next();//將迭代器的指針移向下一個(gè),并將迭代當(dāng)前指向的元素返回System.out.println(str);5)雙列集合Map
Mapmap=newHashMap();map.put("a","aaa");map.put("b","bbb");map.put("c","ccc");//傳統(tǒng)方式迭代1//1.獲得所有的keySetkeys=map.keySet();//2.迭代keys獲得所有的keyIteratoriter=keys.iterator();while(iter.hasNext()){
Stringkey=(String)iter.next();//abc//3.根據(jù)key獲得對應(yīng)的value收集整理}System.out.println("---------------------------------");//傳統(tǒng)方式2,必須掌握這種方式//1.獲得所有的鍵值對Entry對象Setentrys=map.entrySet();//2.迭代出所有的entryiter=entrys.iterator();while(iter.hasNext()){}System.out.println("-------------------------------------");System.out.println("增強(qiáng)for循環(huán)迭代,");//增強(qiáng)for循環(huán)迭代,//原則上map集合是無法使用增強(qiáng)for循環(huán)來迭代的,//因?yàn)樵鰪?qiáng)for循環(huán)只能針對實(shí)現(xiàn)了Iterable接口的集合進(jìn)行迭代//Iterable是jdk5中新定義的接口,就一個(gè)方法iterator方法//只有實(shí)現(xiàn)了Iterable接口的類,才能保證一定有iterator方法//java有這樣的限定是因?yàn)樵鰪?qiáng)for循環(huán)內(nèi)部還是用迭代器實(shí)現(xiàn)的//而實(shí)際上,我們可以通過某種方式來使用增強(qiáng)for循環(huán)for(Objectobj:map.entrySet()){}//obj依次表示EntryMap.Entryentry=(Entry)obj;System.out.println(entry.getKey()+"="+entry.getValue());Map.Entryentry=(Entry)iter.next();//分別獲得key和valueStringkey=(String)entry.getKey();Stringvalue=(String)entry.getValue();System.out.println(key+"="+value);Stringvalue=(String)map.get(key);System.out.println(key+"="+value);6)集合迭代注意問題
//在使用迭代器迭代集合的過程中,不能對集合進(jìn)行增刪操作@Testpublicvoidtest4(){
Listlist=newArrayList();list.add("wangwu");list.add("zhangsan");list.add("lisi");Iteratoriter=list.iterator();while(iter.hasNext()){Stringname=(String)iter.next();if("wangwu".equals(name)){收集整理}@Testpublicvoidtest5(){}Listlist=newArrayList();list.add("aa");list.add("bb");//使用ListIterator迭代器ListIteratorlistIterator=list.listIterator();while(listIterator.hasNext()){}System.out.println(list.size());listIterator.next();//迭代過程中增加元素listIterator.add("cc");}System.out.println(list.size());//從集合中刪掉//list.remove(name);//迭代過程中刪除元素需要調(diào)用迭代器的方法//刪除我迭代的集合被我迭代的最后一個(gè)元素iter.remove();}//1247)增強(qiáng)for循環(huán)注意問題
//在使用增強(qiáng)for循環(huán)時(shí),不能對元素進(jìn)行賦值int[]arr={1,2,3};for(intnum:arr){}System.out.println(arr[1]);num=0;
4.可變參數(shù)
1)jdk5中方法的形參可以定義為可變參數(shù),傳入實(shí)參個(gè)數(shù)可變//設(shè)計(jì)一個(gè)方法求n個(gè)數(shù)的和publicstaticintgetSum(int...arr){
//可變參數(shù)在方法中仍被看做一個(gè)數(shù)組intsum=0;for(intnum:arr)sum+=num;收集整理}returnsum;
2)Arrays.asList為例演示傳入不同參數(shù)的情況//list長度為3Listlist=Arrays.asList("a","b","c");//list長度為1,因?yàn)榭紤]1.4語法String[]arr={"a","b","c"};Listlist=Arrays.asList(arr);//同時(shí)符合1.4和1.5的語法,此時(shí)會(huì)優(yōu)先考慮1.4的語法//原因是有了新功能要保證以前的代碼不出錯(cuò),向后兼容//現(xiàn)在就需要將arr作為一個(gè)元素存入集合Objectobj=arr;Listlist2=Arrays.asList(obj);//此時(shí)只符合1.5的語法,不符合1.4的語法,沒有歧義//優(yōu)先考慮1.4,所以數(shù)組會(huì)拆開Listlist3=Arrays.asList(newObject[]{arr});//System.out.println(list3.size());//基本數(shù)據(jù)類型數(shù)組只符合1.5的語法int[]nums={1,2,3};list=Arrays.asList(nums);System.out.println(list.size());5.枚舉
問題:對象的某個(gè)屬性的值不能是任意的,必須為固定的一組取值其中的某一個(gè)解決辦法:
1)在setGrade方法中做判斷,不符合格式要求就拋出異常
2)直接限定用戶的選擇,通過自定義類模擬枚舉的方式來限定用戶的輸入寫一個(gè)Grade類,私有構(gòu)造函數(shù),對外提供5個(gè)靜態(tài)的常量表示類的實(shí)例3)jdk5中新定義了枚舉類型,專門用于解決此類問題
4)枚舉就是一個(gè)特殊的java類,可以定義屬性、方法、構(gòu)造函數(shù)、實(shí)現(xiàn)接口、繼承類//枚舉類就是一個(gè)java類,也可以聲明屬性,方法,構(gòu)造函數(shù)publicenumGrade4{}//枚舉類就是一個(gè)java類,也可以繼承抽象和實(shí)現(xiàn)接口publicenumGrade5{A("90-100"),B("80-89"),C("70-79"),D("60-69"),E("0-59");privateStringvalue;privateGrade4(Stringvalue){}publicStringgetValue(){}returnvalue;this.value=value;//抽象類不能創(chuàng)建實(shí)例對象A("90-100"){//new了一個(gè)Grade5的子類實(shí)例收集整理}},B("80-89"){},C("70-79"){},D("60-69"){},E("0-59"){};privateStringvalue;privateGrade5(Stringvalue){}publicStringgetValue(){}//對外提供一個(gè)方法,返回枚舉的本地信息//一個(gè)方法不知道如何實(shí)現(xiàn),可以定義為抽象的publicabstractStringtoLocaleString();returnvalue;this.value=value;//new了一個(gè)Grade5的子類實(shí)例publicStringtoLocaleString(){return"不及格";}//new了一個(gè)Grade5的子類實(shí)例publicStringtoLocaleString(){return"差";}//new了一個(gè)Grade5的子類實(shí)例publicStringtoLocaleString(){return"中";}//new了一個(gè)Grade5的子類實(shí)例publicStringtoLocaleString(){return"良";}publicStringtoLocaleString(){return"優(yōu)";}練習(xí):請編寫一個(gè)關(guān)于星期幾的枚舉WeekDay,要求:
枚舉值:Mon,Tue,Wed,Thu,Fri,Sat,Sun星期一。。。。星期日
收集整理
該枚舉要有一個(gè)方法,調(diào)用該方法返回中文格式的星期。
6.反射
1)java代碼的階段:一段java代碼在程序運(yùn)行期間會(huì)經(jīng)歷三個(gè)階段:source-->class-->runtime2)Class對象:在java中用一個(gè)Class對象來表示一個(gè)java類的class階段
Class對象封裝了一個(gè)java類中定義的成員變量、成員方法、構(gòu)造方法、類名、包名等獲得class對象的三種方式和區(qū)別://1.根據(jù)給定的類名來獲得用于類加載Stringclassname="cn.itcast.reflect.Person";//來自配置文件Classclazz=Class.forName(classname);//此對象代表Person.class//2.如果拿到了對象,不知道是什么類型用于獲得對象的類型Objectobj=newPerson();Classclazz1=obj.getClass();//獲得對象具體的類型//3.如果是明確地獲得某個(gè)類的Class對象主要用于傳參Classclazz2=Person.class;//在java中所有的類型都會(huì)對應(yīng)一個(gè)Class對象intIntegerClassintClazz=int.class;ClassintarrClazz=int[].class;ClassvoidClazz=void.class;3)反射
反射就是獲得一個(gè)java類的各個(gè)組成部分//反射類的成員方法Classclazz=Person.class;Methodmethod=clazz.getMethod(methodName,newClass[]{paramClazz1,paramClazz2});method.invoke();//反射類的構(gòu)造函數(shù)Constructorcon=clazz.getConstructor(newClass[]{paramClazz1,paramClazz2,...})con.newInstance(params...)//反射類的屬性Fieldfield=clazz.getField(fieldName);field.setAccessible(true);field.setObject(value);4)反射用在哪里
到底框架是什么?框架就是將開發(fā)中大量重復(fù)的代碼集中起來寫個(gè)通用的程序框架就是用反射來實(shí)現(xiàn)的,框架需要現(xiàn)在的類調(diào)用將來寫的類
框架是將來的程序員調(diào)用的,框架不能實(shí)現(xiàn)完整的功能,框架只是一些一些通用的代碼;框架要依賴將來寫的類來運(yùn)行.
收集整理
現(xiàn)在寫的類要調(diào)用將來寫的類,我們先針對接口進(jìn)行調(diào)用,將來的類需要實(shí)現(xiàn)接口,那么方法就固定了但是將來寫的類的類名我們無法獲知,這時(shí)就需要調(diào)用者通過配置文件告訴框架具體的類名
7.泛型
1)泛型是一種可變化的類型,類型不確定,需要調(diào)用者來指定
2)用途:一個(gè)類的多個(gè)成員方法用到的參數(shù)類型或返回值類型都是未知的類型,但又需要是同一個(gè)類型,就可將方法的參數(shù)類型定義為泛型,此泛型必須在類上先予以聲明才能在方法中使用一個(gè)方法的多個(gè)參數(shù)和返回值需要是同一個(gè)類型,也可以用泛型來解決,在方法返回值前面聲明泛型
泛型的細(xì)節(jié):
1)泛型到底代表什么類型取決于調(diào)用者傳入的類型,如果沒傳,默認(rèn)是Object類型2)使用帶泛型的類創(chuàng)建對象時(shí),等式兩邊指定的泛型必須一致原因:編譯器檢查對象調(diào)用方法時(shí)只看變量,然而程序運(yùn)行期間調(diào)用方法時(shí)就要考慮對象具體類型了3)等式兩邊可以在任意一邊使用泛型在另一邊不使用(考慮向后兼容)
3.泛型的基本概念
以List為例:念著typeof例,List就是ListtypeofStringList中的E稱為類型參數(shù)變量方法定義參數(shù)形式參數(shù)List中的Integer稱為實(shí)際類型參數(shù)整個(gè)List稱為泛型類型GenericType整個(gè)List稱為參數(shù)化的泛型類型
4.泛型的使用1)使用帶泛型的類時(shí),在創(chuàng)建對象時(shí)可以為泛型指定實(shí)際類型參數(shù),指定的具體類型相當(dāng)于給泛型傳參2)子類在繼承父類的時(shí)候,可以為父類定義的泛型指定實(shí)際類型參數(shù)classBclassAextendsB通過子類A獲得的父類類型就是一個(gè)參數(shù)化的類型3)調(diào)用方法時(shí)傳入?yún)?shù)的具體類型將作為方法中泛型的實(shí)際類型
收集整理
Lesson2Servlet(超級重要)
1.javaweb學(xué)什么
用java語言開發(fā)動(dòng)態(tài)的web資源,接下來就是介紹如何開發(fā)動(dòng)態(tài)的web資源對于java程序員而言,所謂動(dòng)態(tài)web資源就是可以運(yùn)行在服務(wù)器上的java程序2.實(shí)現(xiàn)服務(wù)器管理java程序
開發(fā)人員寫好一個(gè)java類,到底有哪些方法tomcat服務(wù)器是不可能知道的tomcat服務(wù)器欲執(zhí)行我們編寫的java類,就需要知道我們的java類有哪些方法,然后在適當(dāng)?shù)臅r(shí)間調(diào)用這些方法,所以我們在寫的java程序要想運(yùn)行在服務(wù)器上,就必須要實(shí)現(xiàn)一個(gè)特殊的接口Servlet.java
interfaceServlet{...}Servlet接口中就定義了可以被tomcat服務(wù)器調(diào)用的java方法通常來講,我們將實(shí)現(xiàn)了Servlet接口的java類稱之為Servlet編寫好的Servlet需要在web.xml文件中做配置,才能供外界訪問
3.實(shí)現(xiàn)第一個(gè)Servlet程序
3.1寫一個(gè)java類實(shí)現(xiàn)Servlet接口packagecn.itcast.servlet;importjava.io.*;importjavax.servlet.*;publicclassHelloWorldServletextendsGenericServlet{//實(shí)現(xiàn)service方法publicvoidservice(ServletRequestrequest,ServletResponseresponse)throwsServletException,java.io.IOException{//向?yàn)g覽器輸出一句話PrintWriterout=response.getWriter();out.write("helloworld!!!");}publicvoidinit()throwsServletException{//初始化servlet時(shí)被調(diào)用System.out.println("init()");}publicvoiddestroy(){//摧毀servlet時(shí)被調(diào)用System.out.println("destroy()");}}收集整理
3.2.導(dǎo)入servletjar包
setclasspath=%classpath%;D:\\apache-tomcat-6.0.20\\lib\\servlet-api.jar3.3.編譯帶包的類
javac-d.HelloWorldServlet.java
3.4.將包拷貝至day05/WEB-INF/classes目錄下-->發(fā)布web工程
3.5.在web.xml文件中做映射HelloWorldServletcn.itcast.servlet.HelloWorldServletHelloWorldServlet/HelloWorldServlet注意:servlet對象一旦創(chuàng)建就會(huì)駐留在內(nèi)存中,為所有的請求服務(wù),servlet對象什么時(shí)候銷毀?直到服務(wù)器關(guān)閉時(shí)或web應(yīng)用被移除才銷毀
3.6.Servlet執(zhí)行流程圖
收集整理
:8080/day05/...ServletIE瀏覽器服務(wù)器Servlet1:找windows或dns解析出ip2:向服務(wù)器發(fā)送請求3:解析出主機(jī)名4:解析出虛擬目錄(上下文路徑)-day055:找到一個(gè)對應(yīng)web應(yīng)用6:解析出用戶訪問的資源名,找web.xml,找出對應(yīng)的Servlet類名7:反射創(chuàng)建Servlet對象,調(diào)用init方法requesrt8:調(diào)用service方法response9:向response對象輸出一句話,service方法就返回10:service方法返回11:從response中取出響應(yīng)消息,發(fā)送給IE瀏覽器4.用eclipse工具開發(fā)Servlet
4.1.建一個(gè)webproject
4.2.在src下建包,創(chuàng)建一個(gè)java類實(shí)現(xiàn)Servlet接口4.3在Webroot\\WEB-INF\\web.xml做servlet映射4.4配置tomcat服務(wù)器window-->preferences-->tomcat6.x4.5將web工程發(fā)布至tomcat服務(wù)器發(fā)布的web應(yīng)用名稱可以配置:web工程右鍵選properties-->myeclipse-->web默認(rèn)情況使用工程名作為發(fā)布后的web應(yīng)用名4.6啟動(dòng)tomcat服務(wù)器運(yùn)行程序
收集整理
5.HttpServlet對象
一般來講我們開發(fā)一個(gè)Servlet會(huì)去繼承HttpServlet
在eclipse下開發(fā)Servlet可以直接新建一個(gè)Servlet,覆寫HttpServlet的doGet和doPost方法繼承HttpServlet的原因是:HttpServlet實(shí)現(xiàn)了service方法,將ServletRequst和ServletResponse
強(qiáng)轉(zhuǎn)為子類HttpServletRequest和HttpServletResponse,讓我們用起來更加方便,同時(shí),在service方法中,它判斷了請求方式,根據(jù)請求方式來調(diào)用doGet和doPost
二、Servlet細(xì)節(jié)
1.*號統(tǒng)配符
一個(gè)Servlet可以映射為多個(gè)路徑
在映射Servlet路徑時(shí)可以使用/*‘或*.擴(kuò)展名‘的形式注意:兩者不能同時(shí)使用/*具有較高的優(yōu)先級2.load-on-startup元素
元素下可以配置
如果一個(gè)Servlet配置了該項(xiàng),web容器會(huì)在web應(yīng)用被加載時(shí)就初始化該Servlet,數(shù)字越小則越先初始化3.tomcat\\conf\\web.xml
服務(wù)器下所有web應(yīng)用中的web.xml都會(huì)自動(dòng)繼承該文件中所有的配置:8080/day05/a.htmla.html是資源名上面的url訪問的url在web.xml文件中并沒有配置
此時(shí)會(huì)去訪問缺省的Servlet,在tomcat\\conf\\web.xml文件中就配置了一個(gè)缺省的DefaultServletDefaultServlet幫我們?nèi)eb應(yīng)用下讀取a.html文件,并打給瀏覽器,如果沒有發(fā)送404頁面也就說,我們通過ie訪問服務(wù)器訪問的都是Servlet4.Servlet線程安全問題
解決Servlet線程安全問題:加上同步的鎖(lock)實(shí)現(xiàn)SingleThreadModel接口的Servlet
服務(wù)器會(huì)做判斷,當(dāng)有請求過來,如果Servlet對象忙著呢,服務(wù)器會(huì)再創(chuàng)建一個(gè)Servlet對象為用戶提供服務(wù),如果Servlet閑置,就直接提供服務(wù)
這樣的方式實(shí)際上是回避了線程安全問題,單線程訪問Servlet,這樣的方式不可取
Lesson3
一、WEB服務(wù)器1.基本概念
WEB在英語中即表示網(wǎng)頁的意思,它用于表示Internet主機(jī)上供外界訪問的資源以及超鏈接所組成的鏈表放在internet網(wǎng)上供外界訪問的文件或程序被稱為web資源web資源被分為:
靜態(tài)web資源:html、css、jpg動(dòng)態(tài)web資源:Servlet、Jsp
14收集整理
2.什么是WEB服務(wù)器?就是一臺(tái)電腦,安裝了一個(gè)服務(wù)器軟件3.為什么需要安裝WEB服務(wù)器
思考問題:從一臺(tái)計(jì)算機(jī)的IE瀏覽器如何去訪問另一臺(tái)計(jì)算機(jī)中的文件3.1兩臺(tái)計(jì)算機(jī)是如何實(shí)現(xiàn)通訊的?IP地址(計(jì)算機(jī)的唯一標(biāo)識(shí))
IPV44個(gè)字節(jié)的整數(shù),每個(gè)字節(jié)以點(diǎn)號隔開192.168.1.100每個(gè)字節(jié)的取值0~255在計(jì)算機(jī)中程序會(huì)綁定在某一個(gè)端口0~65535盡量用1024以上的連接一臺(tái)計(jì)算機(jī)就需要輸入ip地址和端口號作為接收方,應(yīng)該綁定ip,監(jiān)聽指定的端口
3.2在本地寫程序添加一個(gè)服務(wù),供別人來訪問,假設(shè)監(jiān)聽8888端口3.3編碼實(shí)現(xiàn)了一個(gè)本地服務(wù)器程序作用:管理本地的資源,只要將html頁面放到指定的目錄下,外界就可以訪問了
3.4安裝服務(wù)器的目的:開發(fā)好的web資源可以發(fā)布到服務(wù)器上,這樣外界就可以通過瀏覽器訪問了
源程序:MyServer.java
//ServerSocket對象可以監(jiān)聽端口ServerSocketserversocket=newServerSocket(6666);while(true){Socketsocket=serversocket.accept();//等待客戶端的連接請求,一旦有請求過來,就結(jié)束阻塞,返回客戶端對象//一旦有客戶來訪問,就另開一個(gè)新線程去提供服務(wù),main線程繼續(xù)等待下一個(gè)客戶的連接newThread(newMyService(socket)).start();}MyService.java//提供服務(wù)InputStreamin=socket.getInputStream();Thread.sleep(200);intlen=in.available();//估計(jì)此流不受阻塞能讀取的字節(jié)數(shù)byte[]buffer=newbyte[len];in.read(buffer);Stringrequest=newString(buffer);//截取第一行StringfirstLine=request.substring(0,request.indexOf("\\n"));StringuriName=firstLine.split("")[1];OutputStreamout=socket.getOutputStream();//根據(jù)需要訪問的資源創(chuàng)建File對象Filefile=newFile("src"+uriName);if(!file.exists()){out.write("對不起!您訪問的資源不存在!別瞎搞!!".getBytes());out.close();return;}//從文件讀,往瀏覽器寫
收集整理FileInputStreamfis=newFileInputStream(file);buffer=newbyte[1024];while((len=fis.read(buffer))>0){out.write(buffer,0,len);}socket.close();二、Tomcat服務(wù)器的安裝和配置
1.使用tomcat6.0.20.rar文件解壓即完成安裝2.tomcat就是一個(gè)java程序,一定會(huì)用到j(luò)re所以需要配置環(huán)境變量java_home配置成jdk的安裝目錄c:\\jdk1.6tomcat的啟動(dòng)是通過startup.bat文件,實(shí)際上startup.bat中是去調(diào)用catalina.bat文件,而且是通過%catalina_home%\\bin\\catalina.bat去找所以為了保證服務(wù)器啟動(dòng)正常,需要配置catalina_home環(huán)境變量為tomcat的安裝目錄3.tomcat的目錄結(jié)構(gòu)
bin:存放一些執(zhí)行文件
conf:存放服務(wù)器的配置文件
lib:存放tomcat所依賴的jar文件logs:存放日志文件temp:存放臨時(shí)文件
webapps:webapplications存放所有的web應(yīng)用程序(web資源)work:tomcat的工作目錄,jsp翻譯成的Servlet就在這個(gè)目錄下4.web應(yīng)用
多個(gè)web資源存放在一個(gè)目錄下即為一個(gè)web應(yīng)用(web應(yīng)用程序、web工程)web應(yīng)用的目錄結(jié)構(gòu)靜態(tài)web資源直接放在目錄下java類放在classes目錄下web.xml文件負(fù)責(zé)管理web應(yīng)用下所有的web資源所有jar包放在lib目錄下
三、WEB應(yīng)用的映射
1.虛擬目錄一個(gè)web應(yīng)用(服務(wù)器上一個(gè)目錄)需要供外界訪問的路徑,需要映射虛擬目錄
在tomcat6中,放在webapps下的web應(yīng)用,服務(wù)器會(huì)自動(dòng)做映射(將文件夾名稱作為虛擬路徑)對于webapps目錄外的web應(yīng)用需要手動(dòng)映射虛擬路徑1.1.在server.xml文件可以配置
1.2.在%tomcat目錄%\\conf\\catalina\\localhost下寫一個(gè)xml文件
文件名就是虛擬目錄
收集整理
多級目錄配置aaa#bbb.xml對應(yīng)/aaa/bbb如果文件名是ROOT.xml那就是配置了缺省的web應(yīng)用,訪問時(shí)不需要輸入虛擬目錄2.web.xml
Web.xml的作用:管理web應(yīng)用下所有的web資源
通俗地講,一個(gè)web應(yīng)用下所有的web資源如何被外界訪問都需要在此文件下做映射包括咱們后面學(xué)的Servletjsp都需要在這個(gè)文件中做映射
實(shí)驗(yàn):配置web應(yīng)用的首頁
在web應(yīng)用下新建目錄WEB-INF,在此目錄下新建web.xml文件itcast.html3.域名解析
一個(gè)完整url
http:\\\\:80\\itcast\\index.jsp
協(xié)議名主機(jī)名端口號資源名(uri)IE訪問服務(wù)器的原理,
在IE中輸入的地址中包含域名,域名就需要被翻譯成服務(wù)器的IP,才能訪問到服務(wù)器
收集整理
IE瀏覽器sina服務(wù)器看windows是否注冊了該主機(jī)名DNS服務(wù)器(網(wǎng)絡(luò)服務(wù)商)解析域名,獲得一個(gè)IP4.web應(yīng)用映射的練習(xí):新建一個(gè)web應(yīng)用配置成缺省的web應(yīng)用配置首頁
配置tomcat監(jiān)聽端口為80在windows中注冊主機(jī)名5.虛擬主機(jī)
服務(wù)器允許在一個(gè)IP上配置多個(gè)主機(jī),即虛擬主機(jī):80/index.html中的起了兩個(gè)作用:找DNS服務(wù)器,作為域名被解析為IP通過Host頭告訴服務(wù)器訪問的主機(jī)名
配置方式:在server.xml文件中配置Host元素,需要指定name(主機(jī)名)、appBase(默認(rèn)web應(yīng)用存放目錄)appBase目錄下所有的web應(yīng)用,tomcat會(huì)自動(dòng)映射虛擬路徑
做實(shí)驗(yàn):給新配置的虛擬主機(jī)配置缺省的web應(yīng)用
收集整理
分析web資源訪問過程
訪問一個(gè)a.html靜態(tài)web資源,IE做了什么事
1)將作為域名發(fā)送給DNS,解析成IP地址,訪問一臺(tái)服務(wù)器2)發(fā)送Host頭(),告訴服務(wù)器我要訪問的虛擬主機(jī),服務(wù)器拿著Host頭找匹配的Host元素3)將abc作為虛擬目錄,告訴服務(wù)器我要訪問的web應(yīng)用,服務(wù)器拿著abc找匹配的web應(yīng)用
4)將a.html作為資源名,告訴服務(wù)器我要訪問的web資源,服務(wù)器拿著a.html去web.xml文件中找映射虛擬目錄對應(yīng)是一個(gè)web應(yīng)用的目錄,所以虛擬目錄也被我們稱作web應(yīng)用路徑(web應(yīng)用的上下文contextpath)
三、http協(xié)議
1.tcp/ip協(xié)議:網(wǎng)絡(luò)通信協(xié)議(連接)ip協(xié)議:127.0.0.1ip地址對應(yīng)一臺(tái)計(jì)算機(jī)(互聯(lián)網(wǎng)層)tcp高級協(xié)議:三次握手,發(fā)送請求、返回響應(yīng)、傳輸數(shù)據(jù)
2.http協(xié)議是建立在tcp協(xié)議的基礎(chǔ)之上(應(yīng)用層)
3.Http協(xié)議的版本(w3c)
Http1.0:建立連接,發(fā)送一次請求就斷開Http1.1:建立連接,可以無限次發(fā)送請求
(傳輸層)
收集整理
四、http請求消息
http請求消息內(nèi)容:包括一個(gè)請求行、若干消息頭、以及實(shí)體內(nèi)容,其中的一些消息頭和實(shí)體內(nèi)容都是可選的,消息頭和實(shí)體內(nèi)容之間要用空行隔開。請求行POST/itcast/HTTP/1.1消息頭Accept:image/gif,image/x-xbitmap,*/*Referer::8080/itcast/Accept-Language:zh-CN,en-GB;q=0.8,ar-YE;q=0.7,ja-JP;q=0.5,de-CH;q=0.3,en-US;q=0.2Content-Type:application/x-www-form-urlencodedUA-CPU:x86Accept-Encoding:gzip,deflateUser-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;GTB6.5;CIBA)Host:localhost:8080Content-Length:33Connection:Keep-AliveCache-Control:no-cacheCookie:JSESSIONID=B0B3FB4FFB0315B3D3C620548DD4E1EB空一行消息體username=zhangsan&password=123456
1.請求行GET/itcast/a.htmlHTTP/1.1
GET為請求方式:get方式的請求參數(shù)直接跟在url后面,例如:/itcast/a.html?username=aaa&password=111POST方式:post方式請求參數(shù)放在消息體中傳輸,相對安全,get大小限制1K,post無數(shù)據(jù)量限制
2.請求消息頭:IE瀏覽器用于向服務(wù)器說明情況的(瀏覽器使用環(huán)境)Accept:text/html,image/*說明瀏覽器接受的數(shù)據(jù)類型Accept-Charset:ISO-8859-1說明瀏覽器使用的字符編碼Accept-Encoding:gzip,compress說明瀏覽器支持的壓縮格式Accept-Language:en-us,zh-cn說明瀏覽器的語言環(huán)境
Host::80說明瀏覽器要訪問的主機(jī)名If-Modified-Since:Tue,11Jul201*18:23:51GMT文件的修改事件,用于做緩存Referer:說明請求來自哪里,防盜鏈(做實(shí)驗(yàn))User-Agent:Mozilla/4.0(compatible;MSIE5.5;WindowsNT5.0)說明瀏覽器內(nèi)核Cookie向服務(wù)器發(fā)送CookieConnection:close/Keep-Alive說明連接狀態(tài)
Date:Tue,11Jul201*18:23:51GMT客戶端計(jì)算機(jī)時(shí)間
3.實(shí)體內(nèi)容(消息體)
收集整理
瀏覽器向服務(wù)器發(fā)送的數(shù)據(jù),例如上傳的文件、提交的表單等
五、http響應(yīng)消息
http響應(yīng)消息的內(nèi)容包括:一個(gè)狀態(tài)行(類比http請求信息的‖請求行‖)、若干消息頭、以及實(shí)體內(nèi)容,其中的一些消息頭和實(shí)體內(nèi)容都是可選的,消息頭和實(shí)體內(nèi)容之間要用空行隔開。HTTP/1.1200OKServer:Apache-Coyote/1.1Content-Type:text/html;charset=GB18030Content-Length:766Date:Thu,07Jul201*15:40:02GMTMyJSP"index.jsp"startingpagehello
1.狀態(tài)行HTTP/1.1404NotFound
協(xié)議版本:目前普遍采用的都是http1.1響應(yīng)狀態(tài)碼:說明服務(wù)器的響應(yīng)狀態(tài)
常用狀態(tài)碼狀態(tài)碼100~199200~299300~399400~499500~599含義表示成功接收請求,要求客戶端繼續(xù)提交下一次請求才能完成整個(gè)處理過程表示成功接收請求并已完成整個(gè)處理過程,常用200為完成請求,客戶需進(jìn)一步細(xì)化請求。例如,請求的資源已經(jīng)移動(dòng)一個(gè)新地址,常用302、307和304客戶端的請求有錯(cuò)誤,常用404服務(wù)器端出現(xiàn)錯(cuò)誤,常用500200:一切OK
302\\307請求重定向,你訪問我,我通知你訪問另一個(gè)資源304通知瀏覽器去讀緩存
404找不到資源,客戶端的請求有錯(cuò)誤
500服務(wù)器程序出錯(cuò)(服務(wù)器端的程序拋異常了)
收集整理
2.響應(yīng)消息頭服務(wù)器向?yàn)g覽器說明情況(處理結(jié)果)
Location:通知瀏覽器去訪問另一個(gè)資源Server:apachetomcat說明服務(wù)器Content-Encoding:gzip通知瀏覽器數(shù)據(jù)的壓縮格式Content-Length:80通知瀏覽器發(fā)送數(shù)據(jù)的長度Content-Language:zh-cn通知瀏覽器語言環(huán)境Content-Type:text/html;charset=GB2312通知瀏覽器文件的格式和編碼Last-Modified:Tue,11Jul201*18:23:51GMT告訴瀏覽器文件的修改時(shí)間Refresh:1;url=通知瀏覽器自動(dòng)刷新
Content-Disposition:attachment;filename=aaa.zip通知瀏覽器以下載的方式打開資源Set-Cookie:SS=Q0=5Lb_nQ;path=/search發(fā)cookieExpires:-1//3種禁止緩存的頭字段Cache-Control:no-cachePragma:no-cache
Connection:close/Keep-Alive連接狀態(tài)Date:Tue,11Jul201*18:23:51GMT系統(tǒng)時(shí)間
3.實(shí)體內(nèi)容(響應(yīng)消息體)
一般為服務(wù)器發(fā)送給ie瀏覽器的頁面數(shù)據(jù)
六、https協(xié)議
1.https是一種加密協(xié)議能保證數(shù)據(jù)的安全2.不對稱加密對稱加密3.https
1)制作數(shù)字證書
keytool-genkey-aliastomcat-keyalgRSA
2)將證書拷貝至tomcat\\conf
3)修改server.xml文件配置https連接器
收集整理
4)重啟服務(wù)器打開ie訪問https://localhost:84435)ie中安裝證書
繼續(xù)瀏覽
查看證書
收集整理
安裝證書
刪除證書:
收集整理
Lesson5
一、ServletConfig對象
作用:封裝Servlet初始化參數(shù)
1.可以在web.xml文件中Servlet元素下為Servlet配置初始化參數(shù)nameaaaa2.web容器在初始化Servlet時(shí),會(huì)將初始化參數(shù)封裝到一個(gè)ServletConfig對象中,傳給init方法3.我們在Servlet中覆寫init方法,就可以獲得ServletConfig
4.父類GenericServlet中定義了一個(gè)成員變量用于記住此對象,并提供了getServletConfig方法我們可以直接調(diào)用此方法獲得config對象
5.再調(diào)用getInitParameter(name)方法獲得想要配置項(xiàng)//指定編碼//獲得ServletConfig對象ServletConfigconfig=getServletConfig();Stringencoding=config.getInitParameter("encoding");
收集整理System.out.println("encoding="+encoding);二、ServletContext對象:ServletContext被稱為servlet的上下文1.ServletContext對象代表整個(gè)web應(yīng)用
2.ServletContext對象是一個(gè)“域”對象(即:可以存儲(chǔ)數(shù)據(jù)的對象)
ServletContext對象的內(nèi)部維護(hù)了一個(gè)map集合,key是String類型value是Object類型classServletContext{privateMapmap;}
3.ServletContext作為域?qū)ο,多個(gè)Servlet可以共享數(shù)據(jù)Servlet6//1.獲得ServletContext對象ServletContextcontext=getServletContext();//2.存入域context.setAttribute(—name‖,—zhangsan‖);Servlet7//獲得context域,getAttributeStringname=(String)getServletContext().getAttribute("name");4.獲取web應(yīng)用的初始化參數(shù)getContext().getInitParameter(—name‖);
5.統(tǒng)計(jì)一個(gè)web應(yīng)用的訪問量
在context域中維護(hù)一個(gè)count變量訪問Servlet時(shí),取出變量加1
6.實(shí)現(xiàn)請求轉(zhuǎn)發(fā)
實(shí)現(xiàn)請求轉(zhuǎn)發(fā)需要用到轉(zhuǎn)發(fā)對象RequestDispatcher,RequestDispatcher有一個(gè)forward方法能轉(zhuǎn)發(fā)請求7.如何讀取工程中的文件(分兩種情況)7.1.讀取web工程下的資源文件//獲得絕對路徑StringrealPath=ServletContext.getRealPath(相對web應(yīng)用的路徑);注意URLurl=ServletContext.getResource();web的url//獲得與文件關(guān)聯(lián)的流InputStreamin=ServletContext.getResourceAsStream(—WEB-INF/classes/config.properties‖;7.2讀取java工程下的文件
//不能相對虛擬機(jī)目錄不能用絕對路徑//只能類加載的方式讀//獲得流ClassLoaderclassLoader=Demo.class.getClassLoader();InputStreamin=classLoader.getResourceAsStream("a.txt");收集整理//獲得絕對路徑URLurl=Demo.class.getClassLoader().getResource("a.txt");Stringpath=url.getPath();
類加載方式缺點(diǎn)
1)不能讀取類路徑以外文件
2)由于需要加載到內(nèi)存,不能讀大文件3)web工程中如果用類加載的方式讀
類加載實(shí)際上讀取的是內(nèi)存中加載的文件,此時(shí)將讀不到硬盤上資源文件的修改解決辦法:通過絕對路徑去讀硬盤上的文件避開內(nèi)存的文件例如:Demo.Class.getClassLoader().getResource("a.txt").getPath()
三、Servlet緩存
HttpServlet的Service()方法中的代碼//調(diào)用方法longlastModified=getLastModified(req);//如果為-1,就直接放行,給最新的if(lastModified==-1){doGet(req,resp);}//方法返回不是-1else{//讀取IE發(fā)送的頭If-Modified-SincelongifModifiedSince=req.getDateHeader(HEADER_IFMODSINCE);//拿著客戶端的時(shí)間頭和方法的返回值比較if(ifModifiedSince<(lastModified/1000*1000)){//Iftheservletmodtimeislater,calldoGet()//Rounddowntothenearestsecondforapropercompare//AifModifiedSinceof-1willalwaysbeless//方法的返回值大于ie發(fā)送過來的時(shí)間頭//重新向?yàn)g覽器發(fā)送了一個(gè)時(shí)間頭maybeSetLastModified(resp,lastModified);//放行,發(fā)送頁面doGet(req,resp);}else{//方法的返回值沒有大于ie發(fā)送過來的時(shí)間頭//發(fā)送304狀態(tài)碼,讓用戶去讀緩存resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);}}
收集整理
Lesson6一、中文亂碼問題
1.出現(xiàn)亂碼的原因
1)在計(jì)算機(jī)中數(shù)據(jù)以二進(jìn)制的形式進(jìn)行存儲(chǔ)的,數(shù)據(jù)的傳輸也是通二進(jìn)制的形式2)需要存字符,會(huì)出現(xiàn)字符與字節(jié)之間的轉(zhuǎn)換(輸入字符讀到的字符)3)字符和字節(jié)之間如何實(shí)現(xiàn)轉(zhuǎn)換?都是通過查碼表
4)字符到字節(jié)是編碼,字節(jié)到字符是解碼,編碼和解碼用到了不同碼表就會(huì)出現(xiàn)亂碼問題2.解決亂碼
1)拿到亂碼基本上都是由于解碼錯(cuò)誤導(dǎo)致的,解決辦法,重新編碼再解碼2)以后將文件交給解析器,出現(xiàn)亂碼,首先想到是否通知?jiǎng)e人文件的編碼格式
Servlet對象一旦創(chuàng)建就駐留在內(nèi)存,
Request和response對象,web容器會(huì)針對每次用戶的請求創(chuàng)建一個(gè)request和response請求結(jié)束,響應(yīng)發(fā)給ie。Request和response對象就會(huì)立即被銷毀
二、Response對象
1.responsegetWriter方法獲得字符流,用于向?yàn)g覽器輸出字符數(shù)據(jù)","p":{"h":17.043,"w":315.406,"x":180.929,"y":729.538,"z":83},"ps":null,"s":{"lette收集整理
中文亂碼問題
Response中國Tomcatweb容器中國默認(rèn)編碼iso-8859-16363utf-8989789IE瀏覽器6363>??gb2312解錯(cuò)碼ServletgetWriter().write(—中國‖)2.文件下載
文件名中文亂碼問題
由于文件名是跟著content-disposition頭發(fā)送給瀏覽器的
凡是http頭的數(shù)據(jù)都會(huì)經(jīng)過url編碼,編成全世界通用的符號,這樣傳輸過程中才不會(huì)亂碼3.請求重定向
發(fā)送302狀態(tài)碼和location頭ie向?yàn)g覽器發(fā)送了兩次請求第一次直接請求資源,第二次重定向的頁面地址欄是有變化
4.getWriter和getOutputStream不能同時(shí)使用,有沖突response的流我們不用關(guān)閉,交給web容器去管理
三、Request對象
1.request幫助我們?nèi)~@取ie瀏覽器發(fā)送給服務(wù)器的請求消息(請求行消息頭消息體)2.request獲得請求參數(shù):getParameter()和getParameterValues()
收集整理
3.request中文參數(shù)亂碼問題
IE老張url編碼utf-8%E8%80%81%E5%BC%A0tomcatweb容器%E8%80%81%E5%BC%A0request對象解碼iso-8859-1è亂碼程序setCharacterEncoding設(shè)置request編碼Stringdata=getParameter()Request中文參數(shù)亂碼的解決方法:1.表單提交post方式下:request.setCharacterEncoding(—utf-8‖);//指定處理消息體的解碼方式2.表單提交get方式下:1)手動(dòng)解決亂碼問題byte[]bytes=username.getBytes("iso-8859-1");Stringstr=newString(bytes,"utf-8");2)在%tomcat%\\conf\\server.xml中找到當(dāng)前連接器元素Connector配置URIEncoding屬性它用于指定web容器的url解碼方式3)配置useBodyEncodingForURI屬性指定為true用于讓tomcat按照處理消息體的編碼方式處理消息頭
超鏈接提交參數(shù):也是使用get方式提交,(和表單的區(qū)別是,表單提交,ie會(huì)自動(dòng)進(jìn)行url編碼)而超鏈接提交,ie不進(jìn)行url編碼,此時(shí)我們需要將超鏈接中的中文參數(shù)手動(dòng)進(jìn)行url編碼.同理:在服務(wù)器端的處理方式和表單get方式的處理一樣4.請求轉(zhuǎn)發(fā)
Servlet負(fù)責(zé)處理用戶的請求,處理完的結(jié)果交給jsp來做顯示(在Servlet中不輸出任何數(shù)據(jù),所有數(shù)據(jù)的顯示都交給jsp)獲得RequestDispatcher對象做請求轉(zhuǎn)發(fā),1.請求轉(zhuǎn)發(fā)時(shí),需要將處理結(jié)果存入request域帶給jsp2.請求轉(zhuǎn)發(fā)時(shí),web容器(如:tomcat)會(huì)清空response中的數(shù)據(jù)3.轉(zhuǎn)發(fā)后,無法向response輸入數(shù)據(jù)
面試題:請求轉(zhuǎn)發(fā)forward和包含include的區(qū)別
收集整理
Forward的時(shí)候,web容器會(huì)清空response的數(shù)據(jù),并且轉(zhuǎn)發(fā)之后,當(dāng)前Servlet就無法再寫入數(shù)據(jù)了Include的時(shí)候,web容器會(huì)讓兩個(gè)Servlet的數(shù)據(jù)都寫入response
mvc的過程
1)用戶發(fā)送請求(提交表單,超鏈接)
2)Servlet做處理,將數(shù)據(jù)(響應(yīng)結(jié)果)封裝到j(luò)avabean對象3)將javabean對象存入request域4)請求轉(zhuǎn)發(fā)給jsp
5)jsp頁面中從request域取出數(shù)據(jù)做顯示
ServletIE瀏覽器javabeanjspWeb資源訪問的流程
1.客戶端(IE)發(fā)送請求給服務(wù)器2.用一個(gè)Servlet來響應(yīng)客戶的需求基本上分為兩種:1)查看數(shù)據(jù)請求轉(zhuǎn)發(fā)給jsp做顯示
2)用戶登陸\\購買商品完成某一個(gè)特定的功能結(jié)果都是成功或失敗請求重定向到一個(gè)目標(biāo)資源
面試題:請求轉(zhuǎn)發(fā)和請求重定向的區(qū)別?
1)請求重定向地址欄有變化請求轉(zhuǎn)發(fā)地址欄無變化
2)請求重定向客戶端向服務(wù)器發(fā)送兩次請求請求轉(zhuǎn)發(fā)發(fā)送一次請求3)應(yīng)用場景:一件事情做完了,應(yīng)該做第二件事情了,就請求重定向(用戶登陸、購物)Servlet處理完了,讓jsp做顯示,用請求轉(zhuǎn)發(fā)(mvc設(shè)計(jì)模式)
收集整理
web應(yīng)用中的路徑怎么寫?
讀取web中的文件用context讀取,嚴(yán)禁用絕對路徑,通通以‖/‖開頭
原則:就看路徑是給瀏覽器用的還是給服務(wù)器用的,
給瀏覽器用的,要加上web應(yīng)用的名稱給服務(wù)器用的,斜線”/”即表示:當(dāng)前web應(yīng)用(/表示web應(yīng)用,不用加web應(yīng)用的名稱)各種場景:
1)請求轉(zhuǎn)發(fā):地址是給服務(wù)器用的:/表示web應(yīng)用,不用加web應(yīng)用的名稱/a.jspweb.xml文件中用到了路徑:地址是給服務(wù)器用的,不需要加web應(yīng)用/b.jsp/servlet/Servlet12)請求重定向:路徑給瀏覽器用的,所以需要加上web應(yīng)用名稱/day06/a.jsp3)超鏈接:路徑給瀏覽器用的,所以需要加上web應(yīng)用名稱/day06/a.jsp4)表單的action提交:路徑給瀏覽器用的,/day06/a.jsp5)img標(biāo)簽的src屬性:路徑給瀏覽器用的,/day06/a.jpg6)scriptsrc:路徑給瀏覽器用的/day06/js/a.js記住:路徑以“/”開頭,請求轉(zhuǎn)發(fā)不加web應(yīng)用名,其他的全部都要加Lesson7
會(huì)話技術(shù)(包括cookie和sessionCookie是客戶端技術(shù),Session是服務(wù)器端技術(shù))1.會(huì)話,用戶打開瀏覽器,點(diǎn)了一些超鏈接,關(guān)閉瀏覽器的過程
2.會(huì)話過程中會(huì)產(chǎn)生一些數(shù)據(jù),這些數(shù)據(jù)是每個(gè)用戶獨(dú)享的,需要找個(gè)地方存起來3.會(huì)話技術(shù)就是解決上述問題的,Cookie是客戶端技術(shù),Session是服務(wù)器端技術(shù)
Cookie對象
1.Cookie對象的創(chuàng)建
Cookiecookie=newCookie(key,value);2.發(fā)送Cookie
Response.addCookie(cookie);3.獲取指定的Cookie//獲得用戶發(fā)送的所有CookieCookie[]cookies=request.getCookies();//如果沒發(fā)Cookie過來,為null//遍歷找到lastAccessTimeStringlastAccessTime=null;for(inti=0;cookies!=null&&i收集整理
5.顯示用戶最近的瀏覽記錄
兩個(gè)頁面
顯示所有的商品(從數(shù)據(jù)庫找出商品顯示),顯示最近的記錄(讀取客戶發(fā)送的Cookie中存的id,找出書顯示)CookieDemo2
顯示商品的詳細(xì)信息,并向客戶端發(fā)送Cookie,難點(diǎn)如果產(chǎn)生新的Cookie
將客戶端帶過來的Cookie分割后存入集合,根據(jù)不同的情況將新的id加進(jìn)去,迭代集合用分隔符串起來CookieDemo3
Session對象
1.session的原理
request對象有個(gè)方法是getSession()
首先看瀏覽器是否發(fā)送了Cookie(JSESSIONID),如果發(fā)了,拿著id去內(nèi)存中找對應(yīng)的session對象返回;如果沒有發(fā)Cookie或者沒找到對應(yīng)的Session對象,創(chuàng)建一個(gè)新的Session對象getSession(booleancreate)
create為true的時(shí)候,如果內(nèi)存有session就返回,沒有就創(chuàng)建新的
create為false的時(shí)候,意味著只查找不創(chuàng)建,有就返回,沒有不創(chuàng)建,返回null;
2.session的運(yùn)行要依靠cookie來發(fā)送JSESSIONID
如果想讓多個(gè)瀏覽器共享一個(gè)session,我們就需要人工發(fā)送Cookie,并設(shè)置Cookie的有效時(shí)間
3.如果瀏覽器禁用Cookie,那么Session也玩不起來了
要想讓session好用,就需要在頁面跳轉(zhuǎn)時(shí)發(fā)送sessionid
有一個(gè)技術(shù)url重寫:
重寫后的地址會(huì)在原有的url地址的基礎(chǔ)上加上JSESSIONID超鏈接或表單提交的地址,重寫方式如下:StringnewUrl=response.encodeURL(url);請求重定向的地址,
重寫方式如下:StringnewUrl=response.encodeRedirectURL(url);
3.session的應(yīng)用(重點(diǎn))
簡單購物車的實(shí)現(xiàn)ListServletBuyServletListCartServlet
用戶登錄Login.jspLoginServletindes.jspLogoutServlet防止表單重復(fù)提交(2種方法)1.可以用js來做,但是只能增加用戶的體驗(yàn),不能完全防止壞人2.用session做防表單重復(fù)提交FormServletHandleFormServletTokenProcessor
Lesson13JSP入門全稱:javaserverpage
1.web資源的運(yùn)行原理
html:靜態(tài)web資源,DefaultServlet讀取html文件,通過response輸出給IE瀏覽器
收集整理
Servlet:動(dòng)態(tài)web資源,web容器(Servlet引擎)解析web.xml文件,找到url對應(yīng)的java類通過反射創(chuàng)建Servlet對象,調(diào)用service方法Class.forName(—cn.itcast.servlet.Servlet1‖).newInstance();jsp:動(dòng)態(tài)web資源jsp頁面的執(zhí)行過程:(重要)1.jsp頁面在第一次被訪問的時(shí)候,web容器(jsp引擎)會(huì)將jsp翻譯成一個(gè)Servlet,然后調(diào)用servlet的service方法2.jsp翻譯后的Servlet會(huì)被放到%tomcat安裝目錄%\\work\\Catalina\\localhost\\webcontext3.當(dāng)jsp頁面被再次訪問的時(shí)候,web容器會(huì)去直接調(diào)用Servlet的service()方法,所以通常來講jsp只是在第一次被訪問的時(shí)候比較慢4.如果jsp頁面做了修改,此時(shí)web容器會(huì)重新翻譯jsp
2.jsp是什么
實(shí)際上jsp就是Servlet,只是提供了一種比較直觀的書寫方式,因?yàn)閷慾sp就像在寫Htmljsp中可以寫java代碼,有兩種jsp中寫java代碼的方法:1)jsp腳本表達(dá)式
內(nèi)容會(huì)被放到out.print()里面,輸出給瀏覽器格式:
2)jsp腳本片段
內(nèi)容會(huì)原封不動(dòng)地被翻譯到Servlet的service方法中
3.jsp和Servlet的區(qū)別
1)Servlet適合寫java代碼,因?yàn)镾ervlet就是一個(gè)java類在開發(fā)中使用Servlet對用戶發(fā)送的請求進(jìn)行處理并做出響應(yīng)2)jsp適合做數(shù)據(jù)美化,作為數(shù)據(jù)顯示模板因?yàn)閖sp頁面直接書寫HTML標(biāo)簽
3)項(xiàng)目中的web層通常使用mvc設(shè)計(jì)模式Servlet+jsp+javabean其中,Servlet做控制器,處理用戶請求jsp作為顯示模板javabean作為封裝數(shù)據(jù)的實(shí)體4)如何養(yǎng)成一種良好的編碼風(fēng)格在Servlet中應(yīng)避免做任何的數(shù)據(jù)輸出在jsp中應(yīng)避免去直接書寫java代碼,而實(shí)際上要做到這點(diǎn)很難,所以需要用到el和jstl
jsp語法
1.模板元素
在jsp頁面中所有的html標(biāo)簽部分被稱作模板元素,用于對整個(gè)網(wǎng)頁進(jìn)行布局
2.jsp腳本:jsp中的java代碼被稱作jsp腳本
jsp腳本有三種形式
收集整理
1)腳本表達(dá)式:被翻譯到out.print()方法中
2)腳本片段:被翻譯到service()方法中收集整理
jsp引擎iso-8859-1解碼úServlet引擎response編碼iso-8859-19899response.setContentType???úgb2312編碼亂上加亂a.jsp中國gb2312碼9899ServletúIE瀏覽器9899iso-8859-1???úgb2312中國jsp亂碼解決告訴jsp引擎jsp頁面是什么碼,這樣翻譯才不會(huì)錯(cuò);告訴response用什么碼編碼再發(fā)給瀏覽器
三、jsp九個(gè)隱式對象(筆試經(jīng)?)
1.面試題:列舉出jsp頁面的九個(gè)隱式對象,并加以說明
對象變量名(可直接在jsp中使用)configapplicationresponserequestsessionoutpageexceptionpageContext對象類型ServletConfigServletContextHttpServletResponseHttpServletRequestHttpSessionJspWriterthisThrowable(不是每個(gè)jsp都有)PageContext收集整理
2.out對象
JspWriter類型,帶緩沖的字符流(包裝流)BufferedWriter
對response.getWriter()進(jìn)行了包裝,提供了緩沖區(qū),默認(rèn)大小8KB
寫入該流的數(shù)據(jù)最終會(huì)被刷新到response,調(diào)用response.getWriter().write()方法
Question:什么情況下JspWriter會(huì)將數(shù)據(jù)刷新?
1)緩沖區(qū)寫滿(默認(rèn)大小為8kb,可以在page指令中通過buffer屬性設(shè)置緩沖區(qū)大小)2)jsp頁面結(jié)束(此流會(huì)被關(guān)閉,數(shù)據(jù)刷新到底層的流)
注意:
1)jsp中輸出數(shù)據(jù)盡量使用out,不要使用response直接獲得流輸出
原因在于:寫入out的數(shù)據(jù)會(huì)先進(jìn)緩沖區(qū),再刷新到response;如果兩個(gè)都用,會(huì)導(dǎo)致后寫的數(shù)據(jù)顯示在前面2)jsp頁面結(jié)束時(shí),會(huì)自動(dòng)調(diào)用response.getWriter()將數(shù)據(jù)刷新
所以在jsp中不要調(diào)用getOutputStream(),當(dāng)然也不方便做文件下載結(jié)論:在jsp中用out輸出數(shù)據(jù)
3.pageContext對象
主要功能:用于獲得其他8大隱式對象這樣做的意義:
欲移除jsp中的java代碼,就需要將java代碼寫到一個(gè)java類的成員方法中,然后想辦法在jsp頁面中調(diào)用該方法,以達(dá)到代碼復(fù)用的目的.
由于jsp中的java代碼難免會(huì)訪問8個(gè)隱式對象,因?yàn)檫@些對象都是和web開發(fā)相關(guān)的對象,所以要移除這部分java代碼就需要‖將8個(gè)對象傳遞給java類‖的方法,
為了方便,我們通常的做法是:只傳遞一個(gè)pageContext對象過去,這樣在方法中就可以通過該對象很輕松地獲得其他8個(gè)對象了
pageContext也是一個(gè)域?qū)ο?但只在當(dāng)前jsp頁面有效重點(diǎn):
1)默寫9個(gè)對象,(具體描述9個(gè)對象怎么用)
2)理解pageContext對象的意義(獲得其他8個(gè)對象)Btw:pageContext有個(gè)特殊的方法findAttribute()
四、web開發(fā)中的四個(gè)域(重點(diǎn))
范圍由小到大:page(jsp有效)request(一次請求)session(一次會(huì)話)application(當(dāng)前web應(yīng)用)page:PageContext對象request:request對象session:session對象
application:ServletContext對象
1.這4個(gè)對象的生命周期?
生命周期:就是指對象的創(chuàng)建到銷毀的期間
page:jsp頁面被執(zhí)行,生命周期開始,jsp頁面執(zhí)行完畢,生命周期結(jié)束request:用戶發(fā)送一個(gè)請求,開始,服務(wù)器返回響應(yīng),請求結(jié)束,生命周期結(jié)束session:用戶打開瀏覽器訪問,(getSession方法被調(diào)用來)創(chuàng)建session---(開始)當(dāng)session超時(shí)或被聲明失效,該對象生命周期結(jié)束---(結(jié)束)
收集整理
application:web應(yīng)用加載的時(shí)候創(chuàng)建(開始),web應(yīng)用被移除或服務(wù)器關(guān)閉,對象銷毀(結(jié)束)
2.四個(gè)域的作用范圍
2.1.什么是域?為什么把這4個(gè)對象叫做域?qū)ο竽兀坑颍杭捶秶囊馑?/p>
web中的域?qū)ο?可以存儲(chǔ)對象,在作用范圍內(nèi)都可以取到,其內(nèi)部是Map集合的實(shí)現(xiàn)MapclassPageContext{
privateMapmap=newHashMap();privateHttpSessionsession;……}
四種域?qū)ο蟮淖饔梅秶?重要):
page:只在當(dāng)前jsp頁面有效
request:只在當(dāng)前請求有效,每次請求分別對應(yīng)不同的request域?qū)ο?/p>
session:只在一次會(huì)話中有效,會(huì)話結(jié)束就無法取到數(shù)據(jù)了(特殊情況,發(fā)送Cookie)//session:默認(rèn)情況下,同一個(gè)瀏覽器來訪問有效(發(fā)送同一個(gè)sessionid)
application:在一個(gè)web應(yīng)用中有效(只要服務(wù)器不關(guān),web應(yīng)用不移除就可以取數(shù)據(jù))
四個(gè)域?qū)ο蟮姆秶尚〉酱笈帕幸来螢椋簆age
原則:四個(gè)域?qū)ο笤谶x擇的時(shí)候,能用范圍小的絕不用范圍大的
page:數(shù)據(jù)只是暫時(shí)存放在集合中,如果要在jsp頁面的其他地方使用,需要用page(頁面中自定義的map)ps:什么時(shí)候需要用map了,就用page
request:數(shù)據(jù)只是做顯示的,看完了就沒用了,就存request域ps:請求轉(zhuǎn)發(fā),Servlet產(chǎn)生的處理結(jié)果(數(shù)據(jù))交給jsp顯示,session:數(shù)據(jù)給用戶看完了,一會(huì)還要用,會(huì)話結(jié)束了就沒用了ps:用戶登陸,用戶信息發(fā)給客戶端看,看完了,一會(huì)訪問別的頁面還要看用戶信息ps:購物車,購物成功了,給用戶看購物車,待會(huì)隨時(shí)可以查看購物車ps:請求重定向,因?yàn)槭莾纱握埱,第一次請求的?shù)據(jù),第二次請求還要看application:數(shù)據(jù)給一個(gè)用戶用完了,別人還要用ps:聊天室,聊天記錄,需要給所有的用戶看ps:統(tǒng)計(jì)網(wǎng)站在線人數(shù),所有人看到的應(yīng)該是一個(gè)數(shù)
總結(jié):需要定義Map不如用page,請求轉(zhuǎn)發(fā)Servlet帶給jsp的數(shù)據(jù)存request請求重定向帶過去的數(shù)據(jù)存Session,全局的數(shù)據(jù)存application
五、jsp細(xì)節(jié)
只有當(dāng)jsp頁面指定的page指令isErrorPage為true時(shí),才有exception隱式對象Jsp注釋:jsp出錯(cuò):1)被翻譯的Servlet不能編譯,語法錯(cuò),這時(shí)會(huì)報(bào)告是因?yàn)閖sp中的哪行導(dǎo)致不能編譯2)翻譯的Servlet在運(yùn)行期間出現(xiàn)異常,報(bào)告是jsp的哪行導(dǎo)致的異常
收集整理
此時(shí)會(huì)進(jìn)一步報(bào)告導(dǎo)致異常的原因,在Servlet中的哪行出現(xiàn)異常2.jsp映射也是通過servlet元素
六、內(nèi)省(introspect)
1.javabean:一種固定寫法的java類,javabean必須同時(shí)具備以下三種特點(diǎn):
1)必須有無參構(gòu)造函數(shù)
2)屬性必須私有,我們稱為字段3)必須提供標(biāo)準(zhǔn)的get和set方法
例:name字段的getter:StringgetName()settter:voidsetName(Stringname)
2.什么是內(nèi)省introspect?內(nèi)省就是:通過反射的方式訪問javabean
Jdk中的api:PropertyDescriptor類操作Bean的屬性
3.BeanUtils工具包:Apache組織開發(fā)了一套用于操作JavaBean的API(內(nèi)省)
核心類BeanUtilssetProperty(bean,name,value)copyProperties(target,source);BeanUtils的作用:
1.可以支持String到8種基本數(shù)據(jù)類型轉(zhuǎn)換
2.其他引用數(shù)據(jù)類型都需要注冊轉(zhuǎn)換器ConvertUtils.register(Converter,Class)
3.WebUtils工具類:實(shí)現(xiàn)任何request提交的表單封裝到對應(yīng)的javabean
七、jsp標(biāo)簽
為了移除jsp頁面的java代碼,sun公司提供了一些內(nèi)置的標(biāo)簽我們稱為jsp標(biāo)簽,或jsp動(dòng)作元素1.相當(dāng)于RequestDispatcher對象的頁面引入dispatcher.include用于實(shí)現(xiàn)Servlet包含dispatcher.forward用于實(shí)現(xiàn)servlet轉(zhuǎn)發(fā)forward在轉(zhuǎn)發(fā)時(shí),web容器會(huì)清空response中的數(shù)據(jù),轉(zhuǎn)發(fā)之后就無法向response寫入數(shù)據(jù)動(dòng)態(tài)引入方式:在程序運(yùn)行期間引入,jsp被翻譯成兩個(gè)servlet(check?)靜態(tài)引入方式:include指令也能實(shí)現(xiàn)頁面的引入,將兩個(gè)jsp翻譯成一個(gè)Servlet包含和被包含的jsp頁面指令不能發(fā)生沖突(其中,import和pageEncoding可以沖突)2.實(shí)現(xiàn)請求轉(zhuǎn)發(fā)結(jié)合標(biāo)簽傳參,自動(dòng)進(jìn)行url編碼,編碼的方式參照request編碼3.內(nèi)省反射創(chuàng)建javabean,以id作為key存入指定的域其實(shí)在創(chuàng)建之前,會(huì)先去域中找,找到了則不創(chuàng)建4.設(shè)置屬性值
批量5.獲得屬性值
八、web開發(fā)模式
Sun公司針對web開發(fā)提供了兩種模式Model1:jsp+javabean只適合小型應(yīng)用
收集整理
Model2:servlet+jsp+javabeanMVC(重要)
Lesson13:EL表達(dá)式和JSTL標(biāo)簽
1.el全名為ExpressionLanguage。它是一種數(shù)據(jù)訪問語言(不能寫if語句,for循環(huán)等邏輯語句),簡稱:el表達(dá)式2.EL能實(shí)現(xiàn)如下功能:1)使用變量訪問web域中存儲(chǔ)的對象${user}2)訪問javabean的屬性${user.address.city}3)執(zhí)行基本的邏輯運(yùn)算4)直接使用隱式對象5)調(diào)用el函數(shù)
3.el表達(dá)式用在哪里1)在jsp頁面直接輸出數(shù)據(jù)2)在標(biāo)簽中使用el直接為屬性賦值
4.el表達(dá)式獲取數(shù)據(jù)1.在jsp頁面使用el表達(dá)式可以輕松地獲得web域中的對象2.并對javabean、數(shù)組、list、map進(jìn)行取值
5.el表達(dá)式不能寫if,for等邏輯語句,所以需要對web域中的list和map集合進(jìn)行迭代就需要結(jié)合jstl迭代標(biāo)簽JSTL是sun公司開發(fā)的一套標(biāo)簽庫1.JSTL標(biāo)簽的作用:使用JSTL可以在頁面中實(shí)現(xiàn)一些簡單的邏輯,從而替換頁面中的腳本代碼2.如何在頁面中使用JSTL標(biāo)簽?在頁面中使用JSTL標(biāo)簽需完成以下2個(gè)步驟:1)導(dǎo)入jstl.jar和standerd.jar這兩個(gè)JSTL的jar文件。2)在JSP頁面中使用元素導(dǎo)入標(biāo)簽庫。
3.最常用的jstl標(biāo)簽為forEach和if標(biāo)簽
6.el表達(dá)式雖然不能進(jìn)行邏輯判斷和寫for循環(huán),但是el表達(dá)式中可以進(jìn)行邏輯運(yùn)算
40收集整理
7.el表達(dá)式中的保留關(guān)鍵字
二、el中的11個(gè)隱式對象
隱含對象名稱描述對應(yīng)于JSP頁面中的pageContext對象(用于獲取JSP的8個(gè)隱式對象.最主要用途:${pageContext.request.contextPath}代表page域中用于保存屬性的Map對象代表request域中用于保存屬性的Map對象代表session域中用于保存屬性的Map對象pageContextpageScoperequestScopesessionScopeapplicationScope代表application域中用于保存屬性的Map對象paramparamValuesheaderheaderValuescookieinitParam
表示一個(gè)保存了所有請求參數(shù)的Map對象(應(yīng)用:表單回顯)表示一個(gè)保存了所有請求參數(shù)的Map對象,它對于某個(gè)請求參數(shù),返回的是一個(gè)string[]表示一個(gè)保存了所有http請求頭字段的Map對象同上,返回string[]數(shù)組。注意:如果頭里面有—-‖,例Accept-Encoding,則要headerValues[—Accept-Encoding‖]表示一個(gè)保存了所有cookie的Map對象表示一個(gè)保存了所有web應(yīng)用初始化參數(shù)的map對象el表達(dá)式的11個(gè)隱式對象的具體用途(除了pageContext,其余10個(gè)都是map類型)
1.pageContext作用:獲得servlet上下文路徑(web應(yīng)用名稱)最常用代碼:${pageContext.request.contextPath}2.pageScope、requestScope、sessionScope、applicationScope
作用:分別對應(yīng)每個(gè)域所對應(yīng)的那個(gè)map,可以準(zhǔn)確地獲得四個(gè)域中的對象,用于取值
收集整理
3.param、paramValues作用:獲得請求參數(shù),一般用于做表單的回顯4.header、headerValues作用:獲得請求消息頭5.cookie作用:獲得瀏覽器發(fā)送的cookieCookie也是map集合,key是cookie的namevalue是對應(yīng)的cookie對象6.initParam作用:獲得web初始化參數(shù)
三、el函數(shù)
1.我們可以開發(fā)自定義函數(shù),用于調(diào)用java類的方法案例:對頁面輸出的內(nèi)容進(jìn)行html轉(zhuǎn)義實(shí)現(xiàn)步驟:1)編寫一個(gè)java類,定義一個(gè)靜態(tài)方法去tomcat的例子中拷貝一個(gè)現(xiàn)成的%tomcat安裝目錄%\\webapps\\examples\\WEB-INF\\classes2)編寫標(biāo)簽庫描述符(tld)文件,在tld文件中描述自定義函數(shù)找個(gè)現(xiàn)成的修改一下%tomcat安裝目錄%\\webapps\\examples\\WEB-INF\\jsp23)在jsp頁面中導(dǎo)入標(biāo)簽庫即可使用函數(shù)
帖子的內(nèi)容:${myfn:transfer(requestScope.data)}
2.sun公司針對常用的字符串處理在jstl技術(shù)中提供了el函數(shù)中
Lesson17
一、自定義標(biāo)簽入門1.為什么引入標(biāo)簽
jsp頁面作為顯示的模板,應(yīng)盡量使用頁面標(biāo)簽來實(shí)現(xiàn),避免寫java代碼如果在jsp頁面寫java代碼,首先會(huì)令jsp頁面難以閱讀,不利于頁面排版,其次,作為頁面美化人員有可能會(huì)看不懂java代碼,如果將java代碼替換成標(biāo)簽,那么只要是懂html標(biāo)簽的人都能看得懂
2.如何實(shí)現(xiàn)自定義標(biāo)簽
移除jsp頁面中的java代碼其實(shí)很簡單,只需要寫一個(gè)java類實(shí)現(xiàn)Tag接口,在java類中實(shí)現(xiàn)jsp頁面的代碼,在tld標(biāo)簽描述文件中針對標(biāo)簽和java類進(jìn)行映射。案例:實(shí)現(xiàn)標(biāo)簽顯示來訪者的ip
收集整理
實(shí)現(xiàn)步驟:
1)寫一個(gè)類IpTag實(shí)現(xiàn)Tag接口
2)在WEB-INF目錄下新建tld文件,對標(biāo)簽進(jìn)行描述
3)在jsp頁面進(jìn)行調(diào)用
二、傳統(tǒng)標(biāo)簽(已過時(shí),但是框架中還是會(huì)有很多傳統(tǒng)標(biāo)簽)
1.Tag接口執(zhí)行流程:1)創(chuàng)建對象初始化
2)調(diào)用setPageContext方法傳入表示jsp頁面的pageContext3)如果有父標(biāo)簽調(diào)用setParent方法傳入父標(biāo)簽4)調(diào)用setter方法為屬性賦值5)調(diào)用doStartTag方法6)執(zhí)行標(biāo)簽體可選7)調(diào)用doEndTag方法
8)調(diào)用release方法釋放資源
2.方法的返回值Tag.EVAL_BODY_INCLUDE執(zhí)行標(biāo)簽體Tag.SKIP_BODY跳過標(biāo)簽體
Tag.EVAL_PAGE
執(zhí)行剩余頁面
Tag.SKIP_PAGE
跳過剩余頁面
3.Tag接口的子類1)IterationTag接口增加doAfterBody()方法,在方法體執(zhí)行完畢時(shí)被調(diào)用增加返回值EVAL_BODY_AGAIN用于執(zhí)行再次執(zhí)行標(biāo)簽體實(shí)現(xiàn)此接口可以實(shí)現(xiàn)循環(huán)執(zhí)行標(biāo)簽體
一般通過繼承默認(rèn)實(shí)現(xiàn)類BodyTagSupport來實(shí)現(xiàn)該標(biāo)簽2)BodyTag接口
增加setBodyContent(BodyContentb)方法傳入標(biāo)簽體
我們可以通過該方法獲得標(biāo)簽體從而對標(biāo)簽體進(jìn)行操作
4.tld文件
tld是taglibdescriptor的縮寫,tld文件為標(biāo)簽庫描述文件通過tag元素描述一個(gè)標(biāo)簽OutputsHello,WorldhelloWorldcn.itcast.tag.HelloWorldTagempty其中name用于指定標(biāo)簽的名稱(name怎么寫,在jsp頁面怎么寫)
收集整理
tag-class用于指定標(biāo)簽對應(yīng)的java類
body-content用于指定標(biāo)簽對之間可以輸入的內(nèi)容類型empty:表示空標(biāo)簽,即不能有標(biāo)簽體(常用)JSP:標(biāo)簽體不為空,可以寫jsp腳本Scriptless:不能寫jsp腳本,但可以寫表達(dá)式和el(常用)Tagdependent:將原始內(nèi)容提交忽略el表達(dá)式等運(yùn)算
5.標(biāo)簽的屬性
需要在頁面標(biāo)簽中使用屬性需完成以下步驟:1)在標(biāo)簽類中定義一個(gè)屬性2)為屬性添加setter方法3)在tld文件中對屬性進(jìn)行描述實(shí)現(xiàn):元素的子元素用于描述自定義標(biāo)簽的一個(gè)屬性,自定義標(biāo)簽所具有的每個(gè)屬性都要對應(yīng)一個(gè)元素。descriptionaaaatruetrueObjectTypeattribute的子元素元素名descriptionname是否必須指定否是描述用于指定屬性的描述信息。用于指定屬性的名稱。屬性名稱是大小寫敏感的,并且不能以jsp、_jsp、java和sun開頭。用于指定在JSP頁面中調(diào)用自定義標(biāo)簽時(shí)是否必須設(shè)置這個(gè)屬性。其取值包括true和false,默認(rèn)值為false,true表示必須設(shè)置,否則可以設(shè)置也可以不設(shè)置該屬性。rtexprvalue是runtimeexpressionvalue(運(yùn)行時(shí)表達(dá)式)的英文簡寫,用于指定屬性值是一個(gè)靜態(tài)值或動(dòng)態(tài)值。其取值包括true和false,默認(rèn)值為false,false表示只能為該屬性指定靜態(tài)文本值,例如"123";true表示可以為該屬性指定一個(gè)JSP動(dòng)態(tài)元素,動(dòng)態(tài)元素的結(jié)果作為屬性值,例如JSP表達(dá)式。用于指定屬性值的Java類型。required否rtexprvalue否type否6.案例
實(shí)現(xiàn)將標(biāo)簽體循環(huán)執(zhí)行指定次數(shù)的標(biāo)簽Loop
收集整理
三、簡單標(biāo)簽(重點(diǎn))
1.簡單標(biāo)簽SimpleTag
由于傳統(tǒng)標(biāo)簽使用三個(gè)標(biāo)簽接口來完成不同的功能,顯得過于繁瑣,不利于標(biāo)簽技術(shù)的推廣,SUN公司為降低標(biāo)簽技術(shù)的學(xué)習(xí)難度,在JSP2.0中定義了一個(gè)更為簡單、便于編寫和調(diào)用的SimpleTag接口來實(shí)現(xiàn)標(biāo)簽的功能
我們可以通過繼承SimpleTagSupport類來實(shí)現(xiàn)SimpleTag接口
方法詳解:setJspContext方法用于把JSP頁面的pageContext對象傳遞給標(biāo)簽處理器對象setParent方法用于把父標(biāo)簽處理器對象傳遞給當(dāng)前標(biāo)簽處理器對象getParent方法用于獲得當(dāng)前標(biāo)簽的父標(biāo)簽處理器對象setJspBody方法用于把代表標(biāo)簽體的JspFragment對象傳遞給標(biāo)簽處理器對象doTag方法用于完成所有的標(biāo)簽邏輯,包括輸出、迭代、修改標(biāo)簽體內(nèi)容等。在doTag方法中可以拋出javax.servlet.jsp.SkipPageException異常,用于通知WEB容器不再執(zhí)行JSP頁面中位于結(jié)束標(biāo)記后面的內(nèi)容,這等效于在傳統(tǒng)標(biāo)簽的doEndTag方法中返回Tag.SKIP_PAGE常量的情況。Question:方法的調(diào)用順序?
2.開發(fā)案例
開發(fā)防盜鏈標(biāo)簽
開發(fā)標(biāo)簽
開發(fā)標(biāo)簽
choosewhenotherwise
開發(fā)迭代標(biāo)簽Foreach
開發(fā)html轉(zhuǎn)義標(biāo)簽
打包標(biāo)簽庫
收集整理
Lesson9
一、jdbc基本概念
jdbc:JavaDatabaseConnectivity
sun公司為了統(tǒng)一對數(shù)據(jù)庫的操作,定義了一套api,稱之為jdbc這套api完全由接口組成,我們在編寫程序的時(shí)候針對接口進(jìn)行調(diào)用
這些接口交給數(shù)據(jù)庫廠家去實(shí)現(xiàn),不同的數(shù)據(jù)庫廠商會(huì)提供不同的實(shí)現(xiàn)類,這些實(shí)現(xiàn)類被我們稱作數(shù)據(jù)庫的驅(qū)動(dòng)
二、實(shí)現(xiàn)jdbc程序
步驟:1.實(shí)驗(yàn)環(huán)境建user表user.sqlcreatedatabaseday12charactersetutf8collateutf8_general_ci;useday12;createtableusers(idintprimarykeyauto_increment,namevarchar(40),passwordvarchar(40),emailvarchar(60),birthdaydate)charactersetutf8collateutf8_general_ci;insertintousers(name,password,email,birthday)values("zs","123456","zs@sina.com","1980-12-04");insertintousers(name,password,email,birthday)values("lisi","123456","lisi@sina.com","1981-12-04");insertintousers(name,password,email,birthday)values("wangwu","123456","wangwu@sina.com","1979-12-04");
2.導(dǎo)入數(shù)據(jù)庫的驅(qū)動(dòng)
mysql-connector-java-5.0.8-bin.jar
3.編程java程序
//1.注冊數(shù)據(jù)庫的驅(qū)動(dòng)DriverManager.registerDriver(newcom.mysql.jdbc.Driver());//2.建立與mysql數(shù)據(jù)庫的連接用到j(luò)dbcapiStringurl="jdbc:mysql://localhost:3306/day11";收集整理Stringuser="root";Stringpassword="root";Connectionconn=DriverManager.getConnection(url,user,password);//3.創(chuàng)建用于發(fā)送sql語句的Statement對象Statementstmt=conn.createStatement();//4.編寫一句sqlStringsql="select*fromusers";//5.發(fā)送sql,獲得結(jié)果集ResultSetrs=stmt.executeQuery(sql);//6.處理結(jié)果集System.out.println("id|name|password|email|birthday");while(rs.next()){//有第一行intid=rs.getInt("id");//通過列名取值比較直觀Stringname=rs.getString("name");Stringpsw=rs.getString("password");Stringemail=rs.getString("email");Datebirthday=rs.getDate("birthday");System.out.println(id+"|"+name+"|"+psw+"|"+email+"|"+birthday);}//7.關(guān)閉連接釋放資源rs.close();stmt.close();conn.close();三、jdbc程序詳解
1.注冊驅(qū)動(dòng)
DriverManager.registerDriver(newcom.mysql.jdbc.Driver());上面的語句會(huì)導(dǎo)致注冊兩次驅(qū)動(dòng)
原因在于,查看Driver類的源碼會(huì)發(fā)現(xiàn)在靜態(tài)代碼塊中完成了注冊驅(qū)動(dòng)的工作,也就是說注冊驅(qū)動(dòng)其實(shí)很簡單,只需要加載驅(qū)動(dòng)類即可Class.forName(—com.mysql.jdbc.Driver‖);
2.創(chuàng)建數(shù)據(jù)庫的連接
Connectionconn=DriverManager.getConnection(url,user,password);
其中:url,相當(dāng)于數(shù)據(jù)庫的訪問地址,程序員通過url指定需要訪問的數(shù)據(jù)庫
jdbc:mysql:[]//localhost:3306/test?參數(shù)名:參數(shù)值
其中jdbc為主協(xié)議,mysql為子協(xié)議,localhost為主機(jī)名,3306為端口號,test為數(shù)據(jù)庫名
url的后面可以跟參數(shù),常用的參數(shù)有:user=root&password=root&characterEncoding=UTF-8
如果url地址后面跟了user和password,創(chuàng)建Connection對象時(shí)將不必再次傳入值
收集整理
Connectionconn=DriverManager.getConnection(url);
補(bǔ)充:如果訪問的localhost:3306,url可省寫為jdbc:mysql:///test
3.Connection對象:用于表示與某個(gè)數(shù)據(jù)庫之間的連接,在程序中對數(shù)據(jù)庫的所有操作都需要通過此對象來完成常用方法有:createStatement():創(chuàng)建向數(shù)據(jù)庫發(fā)送sql的statement對象。prepareStatement(sql):創(chuàng)建向數(shù)據(jù)庫發(fā)送預(yù)編譯sql的PrepareSatement對象。prepareCall(sql):創(chuàng)建執(zhí)行存儲(chǔ)過程的callableStatement對象。setAutoCommit(booleanautoCommit):設(shè)置事務(wù)是否自動(dòng)提交。commit():在鏈接上提交事務(wù)。rollback():在此鏈接上回滾事務(wù)。
4.Statement對象:用于向數(shù)據(jù)庫發(fā)送sql語句.execute(Stringsql):用于向數(shù)據(jù)庫發(fā)送任意sql語句executeQuery(Stringsql):只能向數(shù)據(jù)發(fā)送查詢語句。
executeUpdate(Stringsql):只能向數(shù)據(jù)庫發(fā)送insert、update或delete語句addBatch(Stringsql):把多條sql語句放到一個(gè)批處理中。executeBatch():向數(shù)據(jù)庫發(fā)送一批sql語句執(zhí)行。
5.ResultSet對象:專門用于封裝結(jié)果集(對于查詢操作特別重要)
存儲(chǔ)的形式就是一種表格的形式,同樣是列+行,說白了就和我們在dos命令行窗口查詢的結(jié)果一樣遍歷方式:一開始游標(biāo)指向結(jié)果集第一行,也就是表頭通過next將游標(biāo)移向下一行,如果沒有下一行,該方法會(huì)返回false獲得當(dāng)前行的數(shù)據(jù)需要調(diào)用get方法:get(intindex)獲得第幾列列數(shù)從1開始get(StringcolumnName)根據(jù)列名獲得值(常用)
數(shù)據(jù)庫的數(shù)據(jù)類型與java中數(shù)據(jù)類型的對應(yīng)關(guān)系
48收集整理
ResultSet對象的常用方法next():移動(dòng)到下一行previous():移動(dòng)到前一行absolute(introw):移動(dòng)到指定行beforeFirst():移動(dòng)resultSet的最前面。afterLast():移動(dòng)到resultSet的最后面。
6.釋放數(shù)據(jù)庫資源
由于數(shù)據(jù)庫的資源非常寶貴,所以用完了一定要記得釋放資源
特別是Connection對象,因?yàn)閿?shù)據(jù)允許的并發(fā)訪問連接數(shù)量往往都比較有限
在java程序中,我們應(yīng)該將最終必須要執(zhí)行的代碼放到finally當(dāng)中釋放資源的代碼if(rs!=null){try{rs.close();}catch(SQLExceptione){e.printStackTrace();}rs=null;}if(stmt!=null){try{stmt.close();
收集整理}catch(SQLExceptione){e.printStackTrace();}stmt=null;}if(conn!=null){try{conn.close();}catch(SQLExceptione){e.printStackTrace();}conn=null;}
四、jdbc實(shí)現(xiàn)crud(createreadupdatedelete)
1.編寫程序?qū)ser表進(jìn)行增刪改查操作
2.防止sql注入在service層進(jìn)行邏輯判斷使用PreparedStatement對象
3.編寫工具類對jdbc程序進(jìn)行優(yōu)化將獲得連接和釋放資源的代碼寫到通用的工具類中
五、jdbc案例
實(shí)現(xiàn)一個(gè)簡單的員工信息管理系統(tǒng),練習(xí)對員工表的crud字段名idnamegenderbirthdayidcarddegreeentrydatepositiondepartment
50說明編號員工姓名性別出生日期身份證號學(xué)歷入職日期部門職位類型varchar(40)varchar(20)varchar(4)datevarchar(20)varchar(20)datevarchar(40)varchar(20)
友情提示:本文中關(guān)于《Java web筆記》給出的范例僅供您參考拓展思維使用,Java web筆記:該篇文章建議您自主創(chuàng)作。
來源:網(wǎng)絡(luò)整理 免責(zé)聲明:本文僅限學(xué)習(xí)分享,如產(chǎn)生版權(quán)問題,請聯(lián)系我們及時(shí)刪除。