java學(xué)習(xí)總結(jié)(基礎(chǔ)加web)
Java考試題
Java基礎(chǔ)部分
1、請簡要描述oop的主要特征,并談?wù)剬@些特征的理解。
Oop主要特征:抽象,封裝,繼承,多態(tài);抽象:忽略與當(dāng)前主題無關(guān)的部分,抓住重點(diǎn)
封裝:使用方法將類的屬性隱藏起來,控制用戶對類的修改和數(shù)據(jù)訪問的程度,
繼承:子類繼承父類的方法和屬性,使程序結(jié)構(gòu)清晰,提高挨罵復(fù)用,一種isa的關(guān)系。多態(tài):不同對象對統(tǒng)一消息進(jìn)行回應(yīng)。一種多種同名方法共存
2、char型變量中能不能存貯一個(gè)中文漢字?為什么?
能,java中編碼方式是unicode,char占2個(gè)字節(jié),一個(gè)漢字剛好兩個(gè)字節(jié)所以可以
3、shorts1=1;s1=s1+1;有什么錯(cuò)?shorts1=1;s1+=1;有什么錯(cuò)?
錯(cuò),需要強(qiáng)制轉(zhuǎn)型為short,+=是java定義的運(yùn)算符故編譯是jvm會自動(dòng)處理
4、請說明break,continue,return的作用。
Break,可用于switch分支一條case語句結(jié)束以后,可用于跳出循環(huán)Contiue:用于跳出里層循環(huán)
Return:也可用于終止循環(huán),有返回類型的方法是用與返回
5、用abstract修飾符修飾的類和方法有什么特點(diǎn)?
修飾的類為抽象類,包含有抽象方法,
修飾的方法,為抽象方法只有方法體而沒有具體實(shí)現(xiàn)
6、protect修飾的方法與不加任何修飾的方法有什么不同?
加上為修飾后訪問為同一包中和該類的子類,不加為默認(rèn)的包訪問權(quán)限。
7、什么是對象?什么是類?它們之間有什么關(guān)系
對象:具有某些屬性和行為的名詞,類:具有相同屬性以及相同行為的一組對象,關(guān)系:對象是類的實(shí)例化
8、請描述對象的初始化順序。
對象初始化順序:加載類,分配內(nèi)存空間,清零,加載變量然后方法。先父類靜態(tài)變量,父類靜態(tài)塊,子類靜態(tài)成員變量,子類靜態(tài)塊,父類非靜態(tài)變量,父類構(gòu)造函數(shù),子類非靜態(tài)變量,子類構(gòu)造函數(shù)
9、什么是繼承?繼承的特性可給面向?qū)ο缶幊處硎裁春锰帲?/p>
繼承:子類繼承父類的方法和屬性,使程序結(jié)構(gòu)清晰,提高代碼復(fù)用,一種isa的關(guān)系。
10、什么是方法的覆蓋?與方法的重載有何不同?方法的覆蓋與屬性的隱藏有何不同?
方法覆蓋:子類重寫與父類同名的方法,擁有相同的參數(shù)名和返回值,多態(tài)的一種體先,重載:具有相同的方法名但是有不同的返回類型或參數(shù)。
屬性隱藏:子類定義與父類同名的屬性,父類的屬性就會被隱藏。
11、請簡述接口和抽象類的區(qū)別。并分別舉例說明應(yīng)用場景。
接口:接口中全是抽象方法,若一個(gè)類實(shí)現(xiàn)這個(gè)接口就必須是先接口中所有的方法。關(guān)鍵字implements和interface抽象類:用關(guān)鍵字abstract修飾,包含抽象方法(僅有方法體而沒有具體實(shí)現(xiàn)),可以包含普通方法和構(gòu)造方法,使用時(shí)不能用new創(chuàng)建實(shí)例
12、說出ArrayList,Vector,LinkedList的存儲性能和特性
ArrayList和Vector都是集合,按數(shù)組的方式存儲,查找比較快,vector是線程安全的,但效率上低于arraylist,Linkedlist:鏈?zhǔn)郊想p向鏈表,按序號索引數(shù)據(jù)進(jìn)行向前向后遍歷,所以插入和刪除數(shù)據(jù)最快。
13、請說明Collection和Collections的區(qū)別。
Collection是一個(gè)j集合的接口,set和list都實(shí)現(xiàn)這個(gè)接口
Collection:是針對集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對各種集合的搜索、排序、線程安全化等操作
14、Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分重復(fù)與否呢?
hashset我們自己區(qū)分的時(shí)候利用迭代器iterator,內(nèi)部利用hashcode然后equals方法實(shí)現(xiàn)區(qū)分是否重復(fù)。
15、Error和Exception它們繼承自哪個(gè)類?有什么區(qū)別?
繼承Throwable這個(gè)類,
區(qū)別:error錯(cuò)誤,一般來說很難回復(fù),如內(nèi)存溢出,exception,則為程序正常運(yùn)行時(shí)永遠(yuǎn)不會發(fā)生的的異常,程序員需要處理。
16、什么情況出現(xiàn)NullPointerException異常?怎樣處理?
使用一個(gè)對象是,對象為null,在適用對象前進(jìn)行判斷
17、請列舉Java類中的方法修飾符,并簡述其含義。
18、try{}里有一個(gè)return語句,那么緊跟在這個(gè)try后的finally{}里的code會不會被執(zhí)行,什么時(shí)候被執(zhí)行,在return前
還是后?
會,在return前
19、Java中如何讀寫文件,請寫出Java代碼實(shí)現(xiàn)讀寫文件的基本過程。20、常見的xml解析方式有哪些?區(qū)別是什么?
Sax,dom:dom一次性全部讀取xml文件,創(chuàng)建一個(gè)一顆文檔樹,故讀取大文件是熟讀緩慢
21、簡要描述數(shù)據(jù)庫連接池的工作機(jī)制,并列出使用數(shù)據(jù)庫連接池的優(yōu)點(diǎn)。
程序運(yùn)行時(shí),創(chuàng)建一定數(shù)量的池連接,比在以后維持不少于這個(gè)數(shù)量的連接。提高程序運(yùn)行的效率
22、對于一個(gè)Linux命令,可以通過哪些方法了解其具體的使用方法。
Help,info,man,使用格式helpls;lshelp;infols;manls;
23、Linux系統(tǒng)中,請簡要描述文件和目錄的訪問權(quán)限的9個(gè)權(quán)限位的作用,請列舉修改權(quán)限的命令。
Xxxxxxxxx;前三位表示所有者的可讀可寫可操作權(quán)限,中間所有者的所在用戶組;后三位是其他用戶,Chmod777要更改權(quán)限的對象。
24、數(shù)據(jù)庫中,什么叫視圖(View),什么叫索引(Index)?什么情況下會用到索引,視圖的主要作用有哪些。
視圖:一張?zhí)摂M的邏輯表。并不包含實(shí)際的數(shù)據(jù),相當(dāng)于一個(gè)窗口,可通過該窗口對數(shù)據(jù)進(jìn)行查詢和修改。作用:使復(fù)雜查詢變得容易,提供數(shù)據(jù)獨(dú)立性,限制數(shù)據(jù)訪問。索引:幫助查找數(shù)據(jù)。用指針加速取回?cái)?shù)據(jù)。
Javaweb部分
1、請簡述對J2EE的理解。
由sun公司提供的一種企業(yè)級基于組件的java開發(fā)規(guī)范。J2EE定義了13種組件如servlet,jsp,jdbc等。2、簡要描述對mvc的理解,并舉例說明在項(xiàng)目中的實(shí)現(xiàn)思路
Mvc是一種開發(fā)模式,優(yōu)點(diǎn):耦合性低,可維護(hù)性高。,分別代表三個(gè)單詞:Modle,Veiw,Control,模型層控制程序的業(yè)務(wù)邏輯,視圖層,是接受用戶輸入和顯示數(shù)據(jù)給用戶與用戶交互,控制層:控制程序走向,模型層與視圖層的中間橋梁。3、Javascript有什么特點(diǎn)?并說明其主要用途。
Javascript:一種腳本語言,是基于事件的面向?qū)ο笳Z言,弱數(shù)據(jù)類型,安全,運(yùn)行速度快,有強(qiáng)大的函數(shù)庫,
主要用途:客戶端驗(yàn)證用戶輸入,給用戶動(dòng)態(tài)的提示。美化頁面。4、什么是servlet容器?它的作用是什么?
Servlet容器:用于創(chuàng)建和維護(hù)servlet,提供一個(gè)運(yùn)行環(huán)境給servlet的東西。5、請描述servlet的生命周期以及在每個(gè)階段所調(diào)用的方法。
實(shí)例化:有容器進(jìn)行。初始化:調(diào)用init()方法。處理請求:根據(jù)請求方式的不同調(diào)用service()中的不同方法如:doget,dopost。銷毀:調(diào)用destroy方法。6、怎樣在web.xml文件中注冊一個(gè)servlet?
主要兩大塊:
7、請描述在servlet中forward和redirect的區(qū)別與聯(lián)系。
Forword:請求轉(zhuǎn)發(fā),服務(wù)器跳轉(zhuǎn),一次請求,地址欄不改變,request對象中的信息不丟失。Redirect:請求重定向,客戶端跳轉(zhuǎn),兩次請求,地址欄改變,request對象中的信息丟失。8、請描述jsp的執(zhí)行過程。
Jsp執(zhí)行經(jīng)過兩個(gè)階段:1、轉(zhuǎn)譯階段,將jsp轉(zhuǎn)譯為servlet,
2、編譯servlet,生成.class文件,
3、調(diào)用.class文件生成html頁面顯示給用戶。
9、如何執(zhí)行一個(gè)線程安全的JSP?
10、Jsp的9個(gè)內(nèi)置對象是什么?他們分別有什么作用。
Jsp九大內(nèi)置對象:page,request,response,session,application,pagecontext,config,exception,out。四個(gè)域?qū)ο螅簅ut輸出信息,e:處理異常,config:拿到一些配置信息。11、請列舉出至少5個(gè)request對象的常用的方法。12、Jsp的四個(gè)域?qū)ο笫鞘裁矗克麄兊?ldquo;域”指的是什么?
Page,requerst,session、,application,域表示有效時(shí)間,及在什么范圍內(nèi)有效。13、請列列舉四個(gè)jsp指令,并說明它們的含義。
Page:設(shè)置頁面屬性,taglib,:標(biāo)簽指令,include:包含指令。14、Jsp有哪些動(dòng)作?作用是什么?
15、請描述Jsp和servlet的區(qū)別與聯(lián)系。
。。。。。。。。
16、請說出在jsp中靜態(tài)包含和動(dòng)態(tài)包含技術(shù)的異同點(diǎn)。
靜態(tài)是先包含再執(zhí)行,動(dòng)態(tài)為先執(zhí)行在編譯。
17、在JSP開發(fā)過程中,對于同一個(gè)用戶的會話,要想在不同的頁面之間共享數(shù)據(jù),可以有幾種選擇?請一一列舉
Request,session,application,cookie,重寫地址欄,隱藏域。18、請說明過濾器的工作原理以及重要的接口。
過濾器:當(dāng)一個(gè)請求到達(dá)是過濾器會進(jìn)行攔截,服務(wù)器響應(yīng)消息時(shí)也會同樣攔截。根據(jù)編寫的故偶濾器確定是否放行和是否要做相應(yīng)的處理。重要接口:filter,filterchain,filterconfig。19、什么是監(jiān)聽器?它的作用是什么,請舉例說明。
監(jiān)聽器是:專門用于對其他對象身上發(fā)生的事件或狀態(tài)改變進(jìn)行監(jiān)聽和相應(yīng)處理的對象,當(dāng)被監(jiān)視的對象發(fā)生情況時(shí)。監(jiān)聽域?qū)ο笞陨淼膭?chuàng)建和銷毀的事件監(jiān)聽器監(jiān)聽域?qū)ο笾械膶傩缘脑黾雍蛣h除的事件監(jiān)聽器
監(jiān)聽綁定到HttpSession域中的某個(gè)對象的狀態(tài)的事件監(jiān)聽器
20、使用http傳輸協(xié)議將客戶端的請求傳送至服務(wù)器端最常用的是哪兩種方式,他們的區(qū)別是什么。
Get,post,
Get:方式相對來說速度較快,當(dāng)傳輸?shù)臄?shù)據(jù)量要小于1kb,傳輸?shù)男畔诘刂窓陲@示,安全性存在隱患。Post:比get方式安全,傳遞的數(shù)據(jù)量也比之要大。21、簡述struts2的工作流程。
Struts2:核心為一個(gè)過濾器,當(dāng)一個(gè)請求到達(dá)的時(shí)候,服務(wù)器對之進(jìn)行攔截,參考struts.xml文件,尋找到對應(yīng)配置的action,尋找到action類,對請求做出相應(yīng)的處理。處理完后返回一個(gè)String,參考struts.xml文件中的配置的result顯示相應(yīng)的頁面給用戶
22、Struts2配置文件struts.xml中有哪些常用的配置項(xiàng),它們分別有什么作用?23、請說明在ognl表達(dá)式中#、$、%的作用。
Ognl表達(dá)式:#是取非valuestack中的值時(shí)使用,如request.還有操作集合是時(shí)也可以用到。
$配置文件中那取action中的值是會使用到。國際化資源文件中引用ognl表達(dá)式%當(dāng)強(qiáng)制聲明為ognl表達(dá)式或字符串是會使用到
24、寫出3組常見的Struts標(biāo)簽,并簡述其作用。
25、valuestack是什么?它的作用是什么?在頁面中怎樣訪問?
Struts的值棧,存放一些請求響應(yīng)信息,直接訪問。26、請簡要描述Struts2中攔截器的主要作用、配置及執(zhí)行流程。
攔截器,servlet中的過濾器相似,當(dāng)客戶端請求到達(dá)是經(jīng)過攔截器,響應(yīng)是也會經(jīng)過,是一種aop的思想。配置:interceptor
Servlet是線程不安全的,采用多線程的方式調(diào)用service方法。CGI就是單線程,所以servlet比之效率高。Servlet實(shí)現(xiàn)單線程的方法:實(shí)現(xiàn)singleThreadmodel。
創(chuàng)建線程的兩種方式:繼承Thread這個(gè)類,或?qū)崿F(xiàn)runnable這個(gè)接口,啟動(dòng)線程:statrt(),啟動(dòng)后會調(diào)用run方法。Sleep和wait()區(qū)別:sleep不會釋放鎖。Wait()釋放鎖,必須有notify()喚醒。多線程中實(shí)現(xiàn)線程安全:利用關(guān)鍵字synchronized,一把鎖,實(shí)現(xiàn)同步。死鎖的條件:互斥條件,不可剝奪資源,循環(huán)等待,請求與保持條件。反射:加載驅(qū)動(dòng),Class.forName(“類的完整類名”)通過一個(gè)class對象拿到其相應(yīng)的方法屬性。組件:就是對數(shù)據(jù)和方法進(jìn)行了簡單封裝。
擴(kuò)展閱讀:Java web入門實(shí)戰(zhàn)總結(jié)[嘔心嚦血之作]
1.Java基礎(chǔ)增強(qiáng)
1.1Eclipse使用最佳實(shí)踐1.1.1常用快捷鍵
Ctrl+1Ctrl+D:
快速修復(fù)(最經(jīng)典的快捷鍵,就不用多說了)刪除當(dāng)前行
復(fù)制當(dāng)前行到下一行(復(fù)制增加)復(fù)制當(dāng)前行到上一行(復(fù)制增加)
當(dāng)前行和下面一行交互位置(特別實(shí)用,可以省去先剪切,再粘貼了)當(dāng)前行和上面一行交互位置(同上)前一個(gè)編輯的頁面
下一個(gè)編輯的頁面(當(dāng)然是針對上面那條來說了)顯示當(dāng)前選擇資源(工程,or文件or文件)的屬性
Ctrl+Alt+↓Ctrl+Alt+↑Alt+↓Alt+↑Alt+←Alt+→Alt+Enter
Shift+Enter在當(dāng)前行的下一行插入空行(這時(shí)鼠標(biāo)可以在當(dāng)前行的任一位置,不一定是最后)Shift+Ctrl+Enter在當(dāng)前行插入空行(原理同上條)Ctrl+QCtrl+LCtrl+MCtrl+/Ctrl+OCtrl+TCtrl+WCtrl+KCtrl+E
定位到最后編輯的地方
定位在某行(對于程序超過100的人就有福音了)最大化當(dāng)前的Edit或View(再按則反之)注釋當(dāng)前行,再按則取消注釋快速顯示OutLine
快速顯示當(dāng)前類的繼承結(jié)構(gòu)關(guān)閉當(dāng)前Editer
參照選中的Word快速定位到下一個(gè)
快速顯示當(dāng)前Editer的下拉列表(如果當(dāng)前頁面沒有顯示的用黑體表示)
Ctrl+Shift+X把當(dāng)前選中的文本全部變味小寫Ctrl+Shift+YCtrl+Shift+F
把當(dāng)前選中的文本全部變?yōu)樾懜袷交?dāng)前代碼
下面的是重構(gòu)的時(shí)候用得到的:Alt+Shift+R
重命名(是我自己最愛用的一個(gè)了,尤其是變量和類的Rename,比手工方法能節(jié)省很多勞動(dòng)力)
Alt+Shift+M
抽取方法(這是重構(gòu)里面最常用的方法之一了,尤其是對一大堆泥團(tuán)代碼有用)
Alt+Shift+CAlt+Shift+L
修改函數(shù)結(jié)構(gòu)(比較實(shí)用,有N個(gè)函數(shù)調(diào)用了這個(gè)方法,修改一次搞定)抽取本地變量(可以直接把一些魔法數(shù)字和字符串抽取成一個(gè)變量,尤其是多處調(diào)用的時(shí)候)
Alt+Shift+FAlt+Shift+IAlt+Shift+VAlt+Shift+Z
把Class中的local變量變?yōu)閒ield變量(比較實(shí)用的功能)合并變量(可能這樣說有點(diǎn)不妥Inline)移動(dòng)函數(shù)和變量(不怎么常用)重構(gòu)的后悔藥(Undo)
1.1.2模塊分離
在實(shí)際的開發(fā)中,盡量讓工作空間(workspace)和項(xiàng)目(Project)分離開來,開發(fā)中使用統(tǒng)一的編碼,一般都設(shè)置成UTF-8(window->preference->general->workspace)
在開發(fā)過程中,要把項(xiàng)目源碼包和測試的源碼包分離開來,因?yàn)闇y試代碼是不需要發(fā)布的,另外,要把測試代碼和項(xiàng)目代碼的編譯輸出目錄分離開來。
1.1.3調(diào)試斷點(diǎn)
關(guān)于Eclipse的調(diào)試,設(shè)置斷點(diǎn),可以通過Run->removeallbreakpoint移除所有的斷點(diǎn)這個(gè)主要是在web開發(fā)的時(shí)候,tomcat自動(dòng)會停在斷點(diǎn)的地方,這個(gè)時(shí)候就需要移除所有斷點(diǎn)。
1.2Java基礎(chǔ)知識1.2.1靜態(tài)導(dǎo)入
示例:
importstaticorg.junit.Assert.*這里表示把Assert類的所有靜態(tài)方法引入,在本文件中如果要使用Assert的靜態(tài)方法就可以不用Assert了。
1.2.2可變參數(shù)
publicstaticintsum(Stringaction,int...params){}這里就表示可變參數(shù),可變參數(shù)必須是最后面的,因?yàn)槿绻环旁诤竺,就無法區(qū)分后面的參數(shù)到底是什么了。
//Dosomethinghere1.2.3foreach
這種方式的循環(huán),強(qiáng)調(diào)的是元素本身,其底層是有迭代器(Iterator)實(shí)現(xiàn)的,需要進(jìn)行對象的同步,所以在效率上比普通的for循環(huán)要低。
在使用foreach循環(huán)的時(shí)候,與奧注意的是修改問題,因?yàn)橥降年P(guān)系,這可能會帶來
一些問題,一般來說,建議如果在需要修改元素的情況下,使用普通的for循環(huán)。
1.2.4拆箱&裝箱
需要注意的是:
對于:Integera=128;Integerb=128;
在-127到128之間的話,a==b是true,否則是false即a、b引用一樣,請看下面的例子:
Integera=128;Integerb=128;
System.out.println(a==b);//falsea=-128;b=-128;
System.out.println(a==b);//true
a=-129;b=-129;
System.out.println(a==b);//falsea=127;b=127;
System.out.println(a==b);//true
1.2.5反射
獲取Class的幾種方式:假設(shè)有類:edu.zhku.cian.User(1)直接使用類名類獲取
Classclazz=User.class;
這種方式用一種缺陷,就是它不會執(zhí)行靜態(tài)代碼塊,別的方式都會執(zhí)行靜態(tài)的代碼塊(2)使用Class.forName獲取,這是最常用的
Classclazz=Class.forName("edu.zhku.cian.User");
會拋出ClassNotFoundException
(3)通過對象的getClass()方法來獲取
Useruser=newUser();
Classclazz=user.getClass();
注意:反射只能是反映靜態(tài)的字節(jié)碼信息,是無法獲得運(yùn)行時(shí)信息的,例如泛型,由于字節(jié)碼是去類型化的,所以在運(yùn)行時(shí)步伐動(dòng)態(tài)獲得泛型類型信息。
1.2.6Annotation-注解
需要掌握的知識:
(1)注解的掃描(2)注解的屬性
1.2.7泛型
作用:
使之類型安全,把運(yùn)行時(shí)的錯(cuò)誤提前到編譯期間,讓錯(cuò)誤提前暴露。關(guān)于
Employeecloned=(Employee)e.clone();
(6)靜態(tài)導(dǎo)入(7)控制臺輸入
JDK5.0先前的版本沒有Scanner類,只能使用JOptionPane.showInputDialog類代替。
5.0:1.4:
Stringinput=JOptionPane.showInputDialog(prompt);intn=Integer.parseInt(input);doublex=Double.parseDouble(input);s=input;
Scannerin=newScanner(System.in);System.out.print(prompt);intn=in.nextInt();doublex=in.nextDouble();Strings=in.nextLine();
(8)格式化輸出、
JDK5.0以前的版本沒有print方法,只能使用NumberFormat.getNumberInstance來代替
(9)內(nèi)容面板代理
在JDK5.0先前的版本中,JFrame,JDialog,JApplet等類沒有代理add和setLayout方法
(10)StringBuilder
JDK5.0引入了StringBuilder類,這個(gè)類的方法不具有同步,這使得該類比StringBuffer
類更高效。
(11)Annotation注解
注解相當(dāng)于一種標(biāo)記,在程序中加了注解就等于為程序打上了某種標(biāo)記,沒加,則等于沒有某種標(biāo)記,以后,javac編譯器,開發(fā)工具和其他程序可以用反射來了解你的類及各種元素上有無何種標(biāo)記,看你有什么標(biāo)記,就去干相應(yīng)的事。標(biāo)記可以加在包,類,字段,方法,方法的參數(shù)以及局部變量上。
看java.lang包,可看到JDK中提供的最基本的annotation。(12)枚舉類型
2.XML
2.1XML基礎(chǔ)2.1.1XML概述
xml是通用數(shù)據(jù)交換格式,不受知識產(chǎn)權(quán)的限制。詳見:E:\\itcast\\review\\0002_Enhance_xml
2.1.2Properties類
加載properties文件的幾種方式:(方式1-4都是要到classpath下面找資源)屬性文件的后綴名可以是任意的//方式一:
InputStreaminStream=LoadConfigTest.class.getResourceAsStream("/config/config.properties");properties.load(inStream);//方式二:
inStream=this.getClass().getResourceAsStream("/config/config.properties");properties.load(inStream);//方式三:inStream=
LoadConfigTest.class.getClassLoader().getResourceAsStream("config/config.properties");//方式四:
inStream=this.getClass().getClassLoader().getResourceAsStream("config/config.pro");properties.load(inStream);//方式五:使用絕對路徑inStream=
newFileInputStream(newFile(..\\\\config.properties"));
7properties.load(inStream);
詳見項(xiàng)目:E:\\itcast\\review\\0002_Enhance_xml------------edu.zhku.cian.pro.LoadConfigTest
2.1.3XML語法
xml文檔聲明
空行和換行的處理,注意下面兩段:
1)2)
廣州廣州
這里的1和2是不同的,在2中還包含了兩個(gè)換行,分別是和廣州之間的,以
及廣州和之間的。
2.1.4xml編碼問題
在進(jìn)行文檔聲明的時(shí)候:
如果聲明的是utf-8,那么文件本省的編碼也應(yīng)該是utf-8,在weindow操作系統(tǒng)下默認(rèn)
新建的xml文件是ASCII編碼的。
如果出現(xiàn)亂碼問題,可以用記事本打開這個(gè)文件,然后另存為,把編碼改成你的文檔聲
明的編碼,如在本例子中的是utf-8。
2.1.5CDATA
(1)CDATA區(qū)全稱為characterdata,以“”結(jié)束,在兩者之間嵌入不想被解析程序解析的原始數(shù)據(jù),解析器不對CDATA區(qū)中的內(nèi)容進(jìn)行解析,而是將這些數(shù)據(jù)原封不動(dòng)地交給下游程序去處理。
(2)CDATA區(qū)中的起始和結(jié)束處有和沒有空格和換行字符是有區(qū)別的
2.1.6特殊字符
&<>""
&<>"'
2.1.7格式良好的XML文件
遵守XML基本語法規(guī)則和規(guī)范的XML文檔就可以稱之為“Well-formedXML”,中文意思就是“格式良好的XML”。
2.1.8XML約束模式語言
先后出現(xiàn)的XML約束模式語言有XMLDTD、XDR、SOX、XMLSchema等等,其中應(yīng)用最廣泛和具有代表意義的是XMLDTD和XMLSchema
2.1.9有效的XML
一個(gè)遵守XML的基本語法規(guī)則、且符合為它指定的某個(gè)XML約束模式的XML文檔就可以稱之為“ValidXML”文檔,中文意思就是“有效的XML”文檔。
2.1.10DTD
全稱DocumentTypeDefinition,DTD文件的編碼應(yīng)該要和xml文件的編碼及其xml聲明的編碼一致,否則不可用。
1.如何在xml中引入外部的dtd,dtd上面的聲明都是指向網(wǎng)絡(luò)上面dtd文件的地址,因?yàn)槲覀儾荒軌蛏暇W(wǎng),無法讓eclipse幫我從網(wǎng)絡(luò)上面下載dtd,就需要將網(wǎng)絡(luò)地址映射到本地dtd地址上面從而對xml進(jìn)行驗(yàn)證.如何映射呢?
2.1在抒寫xml之前要把dtd文件中的xml生命拷貝到當(dāng)前xml中
網(wǎng)絡(luò)地址
2.2在eclipse中..
通過網(wǎng)絡(luò)地址映射本地dtd
window---preferences---xml---xmlCatalog--AddLocation中填寫本地dtd文件的地址KeyType中選擇URIkey中填寫網(wǎng)絡(luò)dtd的地址通過xml聲明中dtd的id
window---preferences---xml---xmlCatalog--AddLocation中填寫本地dtd文件的地址KeyType中選擇PublicIDkey中填寫dtd的Id
2.11XMLSchema與DTD的比較
XMLSchema符合XML語法結(jié)構(gòu)。
DOM、SAX等XMLAPI很容易解析出XMLSchema文檔中的內(nèi)容。XMLSchema則采用與XML文檔同樣的合法性驗(yàn)證機(jī)制。XMLSchema對名稱空間支持得非常好。
XMLSchema比XMLDTD支持更多的數(shù)據(jù)類型,并支持用戶自定義新的數(shù)據(jù)類型。XMLSchema定義約束的能力非常強(qiáng)大,可以對XML實(shí)例文檔作出細(xì)致的語義限制。XMLSchema基本上滿足了關(guān)系模式在數(shù)據(jù)描述上的需要。XMLSchema不能像DTD一樣定義實(shí)體,比DTD更復(fù)雜。
2.2XML解析2.2.1DOM解析
DOMDocumentObjectModel,W3C標(biāo)準(zhǔn),基于信息層次,基于樹或基于對象,一
次性加載到內(nèi)存中。
優(yōu)點(diǎn):編程容易,易于添加和修改樹的元素,遍歷能力強(qiáng)。
缺點(diǎn):需要加載整個(gè)文檔到內(nèi)存,對計(jì)算機(jī)性能和內(nèi)存要求高,尤其是大文檔應(yīng)用場景:由于遍歷能力強(qiáng),DOM解析器常用于xml文檔需要頻繁更改的服務(wù)中。
DOM是用與平臺和語言無關(guān)的方式表示XML文檔的官方W3C標(biāo)準(zhǔn)。DOM是以層次結(jié)構(gòu)組織的節(jié)點(diǎn)或信息片斷的集合。這個(gè)層次結(jié)構(gòu)允許開發(fā)人員在樹中尋找特定信息。分析該結(jié)構(gòu)通常需要加載整個(gè)文檔和構(gòu)造層次結(jié)構(gòu),然后才能做任何工作。由于它是基于信息層次的,因而DOM被認(rèn)為是基于樹或基于對象的。DOM以及廣義的基于樹的處理具有幾個(gè)優(yōu)點(diǎn)。首先,由于樹在內(nèi)存中是持久的,因此可以修改它以便應(yīng)用程序能對數(shù)據(jù)和結(jié)構(gòu)作出更改。它還可以在任何時(shí)候在樹中上下導(dǎo)航,而不是像SAX那樣是一次性的處理。DOM使用起來也要簡單得多。
2.2.2SAX解析
基于事件的,不需要將數(shù)據(jù)存儲在內(nèi)存中,分析能夠立即開始,對于大型XML文檔來說是很好的優(yōu)點(diǎn),一般比DOM要快
SAX處理的優(yōu)點(diǎn)非常類似于流媒體的優(yōu)點(diǎn)。分析能夠立即開始,而不是等待所有的數(shù)據(jù)被處理。而且,由于應(yīng)用程序只是在讀取數(shù)據(jù)時(shí)檢查數(shù)據(jù),因此不需要將數(shù)據(jù)存儲在內(nèi)存中。這對于大型文檔來說是個(gè)巨大的優(yōu)點(diǎn)。事實(shí)上,應(yīng)用程序甚至不必解析整個(gè)文檔;它可以在某個(gè)條件得到滿足時(shí)停止解析。一般來說,SAX還比它的替代者DOM快許多。
選擇DOM還是選擇SAX?對于需要自己編寫代碼來處理XML文檔的開發(fā)人員來說,選擇DOM還是SAX解析模型是一個(gè)非常重要的設(shè)計(jì)決策。DOM采用建立樹形結(jié)構(gòu)的方式訪問XML文檔,而SAX采用的事件模型。
DOM解析器把XML文檔轉(zhuǎn)化為一個(gè)包含其內(nèi)容的樹,并可以對樹進(jìn)行遍歷。用DOM
11優(yōu)點(diǎn):對內(nèi)存要求低,擴(kuò)展能力好
缺點(diǎn):編碼很困難,基于事件模型,很難處理同一個(gè)文檔不同地方的數(shù)據(jù)
解析模型的優(yōu)點(diǎn)是編程容易,開發(fā)人員只需要調(diào)用建樹的指令,然后利用navigationAPIs訪問所需的樹節(jié)點(diǎn)來完成任務(wù)?梢院苋菀椎奶砑雍托薷臉渲械脑。然而由于使用DOM解析器的時(shí)候需要處理整個(gè)XML文檔,所以對性能和內(nèi)存的要求比較高,尤其是遇到很大的XML文件的時(shí)候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務(wù)中。
SAX解析器采用了基于事件的模型,它在解析XML文檔的時(shí)候可以觸發(fā)一系列的事件,當(dāng)發(fā)現(xiàn)給定的tag的時(shí)候,它可以激活一個(gè)回調(diào)方法,告訴該方法制定的標(biāo)簽已經(jīng)找到。SAX對內(nèi)存的要求通常會比較低,因?yàn)樗岄_發(fā)人員自己來決定所要處理的tag.特別是當(dāng)開發(fā)人員只需要處理文檔中所包含的部分?jǐn)?shù)據(jù)時(shí),SAX這種擴(kuò)展能力得到了更好的體現(xiàn)。但用SAX解析器的時(shí)候編碼工作會比較困難,而且很難同時(shí)訪問同一個(gè)文檔中的多處不同數(shù)據(jù)。
2.2.3JDOM解析
JDOM的目標(biāo):使用20%(或更少)的精力解決80%(或更多)Java/XML問題。JDOM的目的是成為JAVA特定文檔模型,簡化與XML的交互并且比使用DOM實(shí)現(xiàn)更快,是第一個(gè)Java特定模型。
JDOM的目的是成為Java特定文檔模型,它簡化與XML的交互并且比使用DOM實(shí)現(xiàn)更快。由于是第一個(gè)Java特定模型,JDOM一直得到大力推廣和促進(jìn)。正在考慮通過“Java規(guī)范請求JSR-102”將它最終用作“Java標(biāo)準(zhǔn)擴(kuò)展”。從201*年初就已經(jīng)開始了JDOM開發(fā)。
JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某
12JDOM自身不包含解析器,它通常使用SAX2解析器來解析和驗(yàn)證輸入XML文檔。JDOM和DOM的不同:
(1)JDOM僅使用具體類而不使用接口,簡化了API,限制了靈活性
(2)API大量使用了Collections類,簡化了那些已經(jīng)熟悉這些類的Java開發(fā)者的使用
JDOM綜合了DOM和SAX解析方式,兼具兩者有點(diǎn),克服兩者缺點(diǎn)。
些方面簡化了API,但是也限制了靈活性。第二,API大量使用了Collections類,簡化了那些已經(jīng)熟悉這些類的Java開發(fā)者的使用。
JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML
問題”(根據(jù)學(xué)習(xí)曲線假定為20%)。JDOM對于大多數(shù)Java/XML應(yīng)用程序來說當(dāng)然是有用的,并且大多數(shù)開發(fā)者發(fā)現(xiàn)API比DOM容易理解得多。JDOM還包括對程序行為的相當(dāng)廣泛檢查以防止用戶做任何在XML中無意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯(cuò)誤)。這也許是比學(xué)習(xí)DOM或JDOM接口都更有意義的工作。
JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗(yàn)證輸入XML文檔(盡
管它還可以將以前構(gòu)造的DOM表示作為輸入)。它包含一些轉(zhuǎn)換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發(fā)布的開放源碼。
2.2.4DOM4J解析
實(shí)例代碼:E:\\itcast\\review\\0002_Enhance_xml針對Java開發(fā)者的易用性和直觀操作。
雖然DOM4J代表了完全獨(dú)立的開發(fā)結(jié)果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XMLSchema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構(gòu)建文檔表示的選項(xiàng),它通過DOM4JAPI和標(biāo)準(zhǔn)DOM接口具有并行訪問功能。
為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復(fù)雜的API的代價(jià),但是它提供了比JDOM大得多的靈活性。
雖然DOM4J代表了完全獨(dú)立的開發(fā)結(jié)果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XMLSchema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構(gòu)建文檔表示的選項(xiàng),它通過DOM4JAPI和標(biāo)準(zhǔn)DOM接口具有并行訪問功能。從201*下半年開始,它就一直處于開發(fā)之中。
為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復(fù)雜的API的代價(jià),但是它提供了比JDOM大得多的靈活性。
在添加靈活性、XPath集成和對大文檔處理的目標(biāo)時(shí),DOM4J的目標(biāo)與JDOM是一樣的:針對Java開發(fā)者的易用性和直觀操作。它還致力于成為比JDOM更完整的解決方案,實(shí)現(xiàn)在本質(zhì)上處理所有Java/XML問題的目標(biāo)。在完成該目標(biāo)時(shí),它比JDOM更少強(qiáng)調(diào)防止不正確的應(yīng)用程序行為。
DOM4J是一個(gè)非常非常優(yōu)秀的JavaXMLAPI,具有性能優(yōu)異、功能強(qiáng)大和極端易用使用的特點(diǎn),同時(shí)它也是一個(gè)開放源代碼的軟件。如今你可以看到越來越多的Java軟件都在使用DOM4J來讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J.
2.2.5解析方式的比較
(1)DOM4J性能最好,連Sun的JAXM也在用DOM4J.目前許多開源項(xiàng)目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J.
(2)JDOM和DOM在性能測試時(shí)表現(xiàn)不佳,在測試10M文檔時(shí)內(nèi)存溢出。在小文檔情況下還值得考慮使用DOM和JDOM.雖然JDOM的開發(fā)者已經(jīng)說明他們期望在正式發(fā)行版前專注性能問題,但是從性能觀點(diǎn)來看,它確實(shí)沒有值得推薦之處。
另外,DOM仍是一個(gè)非常好的選擇。DOM實(shí)現(xiàn)廣泛應(yīng)用于多種編程語言。它還是許
多其它與XML相關(guān)的標(biāo)準(zhǔn)的基礎(chǔ),因?yàn)樗将@得W3C推薦(與基于非標(biāo)準(zhǔn)的Java模型
相對),所以在某些類型的項(xiàng)目中可能也需要它(如在JS中使用DOM)。
(3)SAX表現(xiàn)較好,這要依賴于它特定的解析方式-事件驅(qū)動(dòng)。一個(gè)SAX檢測即將到來的XML流,但并沒有載入到內(nèi)存(當(dāng)然當(dāng)XML流被讀入時(shí),會有部分文檔暫時(shí)隱藏在內(nèi)存中)。
3.Tomcat
3.1Tomcat工作原理3.1.1Servlet容器
Servlet容器的作用是負(fù)責(zé)處理客戶的請求,過程如下:
用戶請求-->Servlet容器獲取請求-->分發(fā)請求(調(diào)用相應(yīng)的Servlet)-->返回用戶結(jié)果
3.1.2Servlet工作模式
1.2.1獨(dú)立的Servlet容器----Tomcat的默認(rèn)工作模式
1.2.2進(jìn)程內(nèi)的Servlet容器1.2.3進(jìn)程外的Servlet容器
3.1.3TomcatWeb應(yīng)用簡介
TomcatWeb應(yīng)用由一些Servlet、HTML、java類、jsp頁面和其他資源構(gòu)成。一
個(gè)TomcatWen應(yīng)用與Tomcat中的Context元素對應(yīng),也就是,一個(gè)Context定義了一個(gè)TomcatWeb應(yīng)用。
3.1.4Tomcat安裝和啟動(dòng)
名詞解釋:
--JDKJavaDevelopToolKit
Java開發(fā)包,包含了很多Java開發(fā)工具(java.exe,
javac.exe......)
--JRE
JavaRuntimeEnvironmentJava運(yùn)行環(huán)境,這是java運(yùn)行的基礎(chǔ)
Java虛擬機(jī),jre目錄下的bin目錄中server和client
--JVMJavaVitualMachine
目錄,這個(gè)是jvm.dll的真正所在,jvm.dll啟動(dòng)后會使用explict的方法
安裝與啟動(dòng)Tomcat步驟:1、安裝JDK
設(shè)置環(huán)境變量:JAVA_HOMED:\\Program\\Study\\Java\\jdk1.6.0_32
CLASSPATH%JAVA_HOME%\\jre\\lib\\rt.jar;.;PATH
%JAVA_HOME%\\bin
--JIT
JavaInTimeJava即時(shí)編譯器,是JVM的一部分,屬于內(nèi)核部分
2、安裝Tomcat
直接在官網(wǎng)下載,解壓縮即可
3、啟動(dòng)與關(guān)閉Tomcat
啟動(dòng):
(1)在命令行模式下切換到Tomcat解壓縮目錄:
F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin
運(yùn)行startup:F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin>startup
(2)直接雙擊startup.bat關(guān)閉:
(1)在命令行模式下切換到Tomcat解壓縮目錄:
F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin
運(yùn)行startup:F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin>shutdown
(2)直接雙擊shutdown.bat
相關(guān)參數(shù)意義:
目錄conf下的server.xmlContext標(biāo)簽:
>reloadable="true|false"docBase="webpath"workDir="catch"
//表示在運(yùn)行時(shí)在classes和lib文件夾下自動(dòng)加載類
//應(yīng)用程序的根目錄//表示緩存文件存放位置
3.2TomcatWeb項(xiàng)目部署3.2.1安裝Tomcat為系統(tǒng)服務(wù)
實(shí)現(xiàn)可以通過windows的service.msc打開的界面進(jìn)行服務(wù)的管理。DOS-->cd到Tomcat/bin目錄下,里面有一個(gè)service.bat文件,運(yùn)行該文件即可,如下命令格式:
運(yùn)行命令:serice.batinstalltomcat6
(其中tomcat6是服務(wù)的名字,可以任意取)
3.2.2卸載Tomcat系統(tǒng)服務(wù)
卸載該服務(wù):
serviceuninstalltomcat6(其中tomcat6是服務(wù)的名字,可以任意取)
3.2.3Web項(xiàng)目結(jié)構(gòu)
/web應(yīng)用的根目錄,該目錄下的所有文件都是可訪問到額該目錄及其子目錄下的文件在瀏覽器中是不可訪問的,web.xml包含wen應(yīng)用的配置屬性,這些屬性由ServletAPI定義
/WEB-INF/classes/WEB-INF/lib
存放web應(yīng)用的所有classes文件存放類文件打包后的jar文件
/WEB-INF
注意:為了部署方便,還目錄下的所有文件可以壓縮為zip文件再更改擴(kuò)展名為war?梢愿鶕(jù)需要在根目錄下建立不同資源文件的子目錄:如js/image
3.2.4Web項(xiàng)目部署
(1)將整個(gè)項(xiàng)目復(fù)制到Tomcat安裝目錄下的webapps目錄下
(2)直接在server.xml中進(jìn)行配置
在server.xml的前面添加一個(gè)Web應(yīng)用環(huán)境:例如:
如果項(xiàng)目的目錄結(jié)構(gòu)如下:--example----WEB-INF------lib------web.xml----index.html
其中的example,就是項(xiàng)目的根路徑
那么訪問index.html的格式::8080/example/index.html
第一個(gè)參數(shù)指定虛擬目錄訪問路徑:如上面這樣子,訪問的格式如下:
:8080/hello/index.html
第三個(gè)表示啟用熱部署,可選,如果path="",表示直接根目錄下就能訪問,即默認(rèn)項(xiàng)
目:
:8080/index.html
3.2.5虛擬主機(jī)映射
所解決的問題:在一個(gè)Tomcat下可以使用多個(gè)默認(rèn)WEB項(xiàng)目,即每一個(gè)虛擬主機(jī)對應(yīng)一個(gè)默認(rèn)項(xiàng)目
(1)在計(jì)算機(jī)上配置虛擬主機(jī)(不同操作系統(tǒng)不同,具體可參見百度)
windows下配置虛擬主機(jī):
dos-->cdC:\\Windows\\System32\\drivers\\etc
下面有一個(gè)hosts文件,打開這個(gè)文件,添加:
127.0.0.1127.0.0.1127.0.0.1
(2)在server.xml中配置虛擬主機(jī)
在原有的標(biāo)簽后面添加一個(gè)Host標(biāo)簽:
(3)啟動(dòng)Tomcat服務(wù)器
服務(wù)器啟動(dòng)之后我們就可以使用下面這個(gè)URL來訪問我們的應(yīng)用了
:8080/index.html:8080/index.html:8080/index.html
3.3HTTP協(xié)議詳解3.3.1什么是HTTP協(xié)議
(1)web瀏覽器和web服務(wù)器之間是一問一答的的交互過程,而要想正確的進(jìn)行交互,就
必須遵循一定的規(guī)則,這個(gè)規(guī)則就是我們所熟悉的HTTP協(xié)議規(guī)范。
(2)HTTP是HypertextTransferProtocol(超文本傳輸協(xié)議)的縮寫,它是TCP/IP協(xié)議子
集中的一個(gè)應(yīng)用層協(xié)議,用于定義web瀏覽器和web服務(wù)器之間數(shù)據(jù)交換的過程及數(shù)據(jù)本身。
(3)HTTP協(xié)議的版本HTTP/1.0、HTTP/1.1、HTTP-NG
(4)深入理解HTTP協(xié)議,對管理和維護(hù)復(fù)雜的WEB站點(diǎn)、開發(fā)具有特殊用途的WEB服
務(wù)器程序具有直接影響。
3.3.2建立TCP連接
TCP傳輸連接建立過程中需要解決三個(gè)基本問題:
TCP協(xié)議采用的是客戶/服務(wù)器模式,主動(dòng)發(fā)起建立連接請求的稱之為客戶,等待
1)確定通信的每一方是否存在
2)允許雙方協(xié)商通信參數(shù),如最大報(bào)文段長度,最大窗口長度以及服務(wù)質(zhì)量等3)分配傳輸實(shí)體可以使用的資源,如緩沖區(qū)大小
并接收連接建立請求的進(jìn)程為服務(wù)器。
傳輸連接建立需要經(jīng)過以下三個(gè)步驟(即所謂的"三次握手"):
假設(shè)主機(jī)[A]為客戶進(jìn)程,主機(jī)[B]為服務(wù)進(jìn)程,現(xiàn)在[A]要與[B]建立傳輸連接。1)第一次握手
2)第二次握手
[B]-->同意[A]與自己建立連接
-->[B]向[A]發(fā)出應(yīng)答報(bào)文段
-->[SYN=1,ACK=1,SEQ=4800(同樣需要分配一個(gè)序號)]-->【AN=1201(確認(rèn)號,即請求報(bào)文中的SEQ+1,
表示序號為1200的報(bào)文段已經(jīng)正確接收
下一次應(yīng)該發(fā)送序號SEQ=1201的報(bào)文段,因此AN有捎帶確認(rèn)的作用)】
[A]-->發(fā)送連接請求報(bào)文段到[B]
這就好像是[A]對[B]說:我希望開始一次新的會話
-->[SYN=1,ACK=0,SEQ=1200(這個(gè)是給這個(gè)報(bào)文段分配一個(gè)序號)]
這就好像[B]對[A]說:好吧,讓我們交談吧
3)第三次握手
[A]-->接收到[B]的應(yīng)答報(bào)文段
這就好像[A]對[B]說:很高興你愿意交談,我們開始吧!
-->在此發(fā)送一個(gè)建立傳輸連接確認(rèn)報(bào)文段
-->[SYN=1,ACK=1,SEQ=1201,AN=4801(即應(yīng)答報(bào)文段的SEQ+1)]
經(jīng)過這三次的握手之后就建立好了[A]和[B]之間的連接,即向應(yīng)用層報(bào)告連接已經(jīng)建立
好了。
目的:看完上面的["三次握手"]之后,你也許知道這三次握手的目的了:
采用三次握手的目的是為防止傳輸連接過程中出現(xiàn)錯(cuò)誤(傳輸延遲等原因)。
3.3.3釋放TCP連接
在用戶數(shù)據(jù)傳輸結(jié)束時(shí),需要釋放傳輸連接,才易于傳輸連接的任何一方都可以釋放連接。
釋放傳輸連接需要四個(gè)步驟(亦即【四次握手】)
當(dāng)關(guān)閉客戶進(jìn)程到服務(wù)進(jìn)程的連接時(shí),服務(wù)端進(jìn)程到客戶端的進(jìn)程可能還沒釋放,使用
四次握手的方式來確保連接都關(guān)閉。
1)第一次握手
[A]-->發(fā)送釋放連接請求報(bào)文段
-->[FIN=1,ACK=0,SEQ=2500]
[A]希望釋放此次連接
2)第二次握手
[B]-->同意釋放連接
-->發(fā)出應(yīng)答報(bào)文段
-->[ACK=1,AN=2501,SEQ=6000]
[B]此時(shí)知道[A]的想法釋放此次連接
3)第三次握手
[B]-->我沒數(shù)據(jù)需要傳輸了
-->釋放服務(wù)端到客戶端的連接-->向[A]發(fā)出釋放連接請求報(bào)文段-->[FIN=1,ACK=0,SEQ=6001]
同意釋放這次連接
4)第四次握手
[A]-->接收到[B]的請求釋放連接報(bào)文段
-->再次發(fā)送釋放連接應(yīng)答報(bào)文段-->[ACK=1,SEQ=2501,AN=6002]
釋放這次連接
3.3.4HTTP1.0會話方式
四個(gè)步驟:
建立連接--》發(fā)出請求信息--》回送相應(yīng)信息--》關(guān)閉連接
HTTP1.0
瀏覽器和web服務(wù)器之間的連接過程是短暫的,每次的連接處理一個(gè)請求和響應(yīng),對
于每一個(gè)頁面的訪問都需要建立一個(gè)獨(dú)立的連接。
3.3.5HTTP1.1會話方式
HTTP1.1的特點(diǎn):
1)在一個(gè)連接上可以傳送多個(gè)HTTP請求和響應(yīng)2)多個(gè)請求和響應(yīng)可以重疊執(zhí)行
3)增加了更多的請求頭和響應(yīng)頭
過程:
建立連接
-->發(fā)送第1個(gè)請求-->發(fā)送第2個(gè)請求-->......
-->發(fā)送第n個(gè)請求-->回送第1次響應(yīng)-->回送第2次響應(yīng)-->......
-->回送第n次響應(yīng)-->關(guān)閉連接
3.3.6HTTP請求消息
請求消息的結(jié)構(gòu):
一個(gè)請求行、若干消息頭、以及實(shí)體內(nèi)容,其中的一些消息頭和實(shí)體內(nèi)容都是可選的,
消息頭和實(shí)體內(nèi)容之間要用空行隔開。
舉例:請求行:消息頭:
Accept:*/*
Accept-Language:en-usConnection:Keep-AliveHost:localhost
Referer:User-Agent:Mozilla/4.0Accept-Encoding:gzip,deflate
GET/books/java.htmlHTTP/1.1
空行:----------
GET請求方式的請求消息中不能包含消息實(shí)體(AJAX)
3.3.7HTTP響應(yīng)消息
響應(yīng)消息的結(jié)構(gòu):
一個(gè)狀態(tài)行、若干消息頭、以及實(shí)體內(nèi)容,其中的一些消息頭和實(shí)體內(nèi)容都是可選的,
消息頭和實(shí)體內(nèi)容之間要用空行隔開。
舉例:狀態(tài)行:消息頭:
Server:Microsoft-IIS/5.0
Date:Thu,13Jul201*05:46:53GMTContent-Length:2291Content-Type:text/htmlCache-control:private
HTTP/1.1200OK
一個(gè)空行:實(shí)體內(nèi)容:
3.3.8HTTP消息頭
(1)使用消息頭,可以實(shí)現(xiàn)HTTP客戶機(jī)與服務(wù)器之間的條件請求和應(yīng)答,消息頭相當(dāng)于服務(wù)器和瀏覽器之間的一些暗號指令
(2)每個(gè)消息頭包含一個(gè)頭字段名稱,然后依次是冒號、空格、值、回車和換行符。
舉例:Accept-Language:en-us
(3)消息頭字段名是不區(qū)分大小寫的,但習(xí)慣上將每個(gè)單詞的第一個(gè)字母大寫(4)整個(gè)消息頭部分中的各行消息頭可按任何順序排列
(5)消息頭又可以分為通用信息頭、請求頭、響應(yīng)頭、實(shí)體頭等四類
(6)許多請求頭字段都允許客戶端在值部分指定多個(gè)可接受的選項(xiàng),多個(gè)項(xiàng)之間以逗號分隔。
舉例:Accept-Encoding:gzip,compress
(7)有些頭字段可以出現(xiàn)多次,例如,響應(yīng)消息中可以包含有多個(gè)“Warning”頭字段。
3.3.9HTTP典型響應(yīng)碼
200(正常)
表示一切正常,返回的是正常請求結(jié)果。
206(部分內(nèi)容)
客戶發(fā)送了一個(gè)帶有Range頭(要求服務(wù)器只返回文檔中的部分內(nèi)容)的GET請求,
服務(wù)器按要求完成了這個(gè)請求。302/307(臨時(shí)重定向)
指出被請求的文檔已被臨時(shí)移動(dòng)到別處,此文檔的新的URL在Location響應(yīng)頭中給出。
304(未修改)
表示客戶機(jī)緩存的版本是最新的,客戶機(jī)應(yīng)該繼續(xù)使用它。
401(未經(jīng)授權(quán))
表示客戶機(jī)訪問的是一個(gè)受口令和密碼保護(hù)的頁面,結(jié)合使用一個(gè)WWW-Authenticate
響應(yīng)頭提示客戶機(jī)應(yīng)重新發(fā)出一個(gè)帶有Authorization頭的請求消息。404(找不到)
服務(wù)器上不存在客戶機(jī)所請求的資源。
500(內(nèi)部服務(wù)器錯(cuò)誤)
服務(wù)器端的CGI、ASP、JSP等程序發(fā)生錯(cuò)誤。
4.IO
4.1概述
IO流用來處理設(shè)備之間的數(shù)據(jù)傳輸Java對數(shù)據(jù)的操作是通過流的方式Java用于操作流的對象都在IO包中流按操作對象分為兩種:字節(jié)流與字符流。
先有字節(jié)流,后有字符流。為什么要出現(xiàn)字符流呢?流按流向分為:輸入流,輸出流。
4.2IO常用基本類
字節(jié)流的抽象基類:
InputStream,OutputStream。字符流的抽象基類:
Reader,Writer。
注:由這四個(gè)類派生出來的子類名稱都是以其父類名作為子類名的后綴。
如:InputStream的子類FileInputStream。如:Reader的子類FileReader。
4.3字符流4.3.1創(chuàng)建文件
創(chuàng)建流對象,建立數(shù)據(jù)存放文件
FileWriterfw=newFileWriter(“Test.txt”);調(diào)用流對象的寫入方法,將數(shù)據(jù)寫入流
fw.write(“text”);
關(guān)閉流資源,并將流中的數(shù)據(jù)清空到文件中。
fw.close();
不寫close方法會有什么結(jié)果呢?---沒有被銷毀,消耗內(nèi)存
如果想在原有文件上繼續(xù)加入新的數(shù)據(jù)呢?---建立文件的時(shí)候,第二參數(shù):trueFileWriterfw=null;try{fw=newFileWriter("Test.txt");fw.write("text");}catch(IOExceptione){System.out.println(e.toString());
}finally{if(fw!=null)try{fw.close();}catch(IOExceptione){System.out.println(e.toString());}}4.3.2讀取文件
建立一個(gè)流對象,將已存在的一個(gè)文件與流進(jìn)行關(guān)聯(lián)。
FileReaderfr=newFileReader(“Test.txt”);創(chuàng)建一個(gè)臨時(shí)存放數(shù)據(jù)的數(shù)組。
char[]ch=newchar[1024];
調(diào)用流對象的讀取方法將流中的數(shù)據(jù)讀入到數(shù)組中。
fr.read(ch);思考:
在加載文件時(shí)候是否是將文件全部加載進(jìn)流-----不是,先讀取部分到緩沖區(qū)為什么定義數(shù)組,要定義多大呢?-----緩沖區(qū),一般是1024FileReaderfr=null;try{fr=newFileReader("c:\\\\test.txt");char[]buf=newchar[1024];intnum=0;while((num=fr.read(buf))!=-1){System.out.println(newString(buf,0,num));}}catch(IOExceptione){System.out.println("read-Exception:"+e.toString());}finally{if(fr!=null){try{fr.close();}
}}catch(IOExceptione){System.out.println("close-Exception:"+e.toString());}4.3.3注意事項(xiàng)
定義文件路徑時(shí),可以用“/”或者“\\\\”。
在創(chuàng)建一個(gè)文件時(shí),如果目錄下有同名文件將被覆蓋。
在讀取文件時(shí),必須保證該文件已存在,否則出異常FileNotFoundException。
練習(xí):Copy一個(gè)文本文件。
思路:可以使用字節(jié)流,也可以使用字符流,看需求,從輸入流讀取到輸出流即可。
4.3.4字符流的緩沖區(qū)
緩沖區(qū)的出現(xiàn)提高了對數(shù)據(jù)的讀寫效率。對應(yīng)類:
BufferedWriterBufferedReader
緩沖區(qū)要結(jié)合流才可以使用。在流的基礎(chǔ)上對流的功能進(jìn)行了增強(qiáng)。
4.3.5IO裝飾模式
對原有類進(jìn)行了功能的改變,增強(qiáng)。裝飾模式的基本格式。
它與繼承有什么不同?--------使用的是組合了解BufferedReader的原理。
4.4字節(jié)流4.4.1概述
基本操作與字符流類相同
但它不僅可以操作字符,還可以操作其他媒體文件例程:
Copy一個(gè)Jpg文件。
4.4.2字節(jié)流的緩沖區(qū)
同樣是提高了字節(jié)流的讀寫效率。通過換成區(qū),可以降低與磁盤的IO操作次數(shù)。練習(xí):
通過幾種方式對MP3的進(jìn)行拷貝,比較它們的效率。使用模板方法設(shè)計(jì)模式自定義MyBufferedInputStream
體現(xiàn)緩沖思想。
read方法返回int類型的原因。
4.4.3轉(zhuǎn)換流
轉(zhuǎn)換流的由來
字符流與字節(jié)流之間的橋梁(編碼轉(zhuǎn)換)方便了字符流與字節(jié)流之間的操作轉(zhuǎn)換流的應(yīng)用
字節(jié)流中的數(shù)據(jù)都是字符時(shí),轉(zhuǎn)成字符流操作更高效。例程:標(biāo)準(zhǔn)輸入輸出。
System類中的字段:in,out。
它們各代表了系統(tǒng)標(biāo)準(zhǔn)的輸入和輸出設(shè)備。默認(rèn)輸入設(shè)備是鍵盤,輸出設(shè)備是顯示器。System.in的類型是InputStream.
System.out的類型是PrintStream是OutputStream的子類FilterOutputStream的子類.標(biāo)準(zhǔn)輸入輸出流示例:
例:獲取鍵盤錄入數(shù)據(jù),然后將數(shù)據(jù)流向顯示器,那么顯示器就是目的地。通過System類的setIn,setOut方法對默認(rèn)設(shè)備進(jìn)行改變。
System.setIn(newFileInputStream(“1.txt”));//將源改成文件1.txt。System.setOut(newPrintStream(“2.txt”));//將目的改成文件2.txt因?yàn)槭亲止?jié)流處理的是文本數(shù)據(jù),可以轉(zhuǎn)換成字符流,操作更方便。BfferedReaderbufr=
newBufferedReader(newInputStreamReader(System.in));
BufferedWriterbufw=
newBufferedWriter(newOutputStreamWriter(System.out));
4.4.4流的應(yīng)用
流是用來處理數(shù)據(jù)的。
處理數(shù)據(jù)時(shí),一定要先明確數(shù)據(jù)源,與數(shù)據(jù)目的地(數(shù)據(jù)匯)。數(shù)據(jù)源可以是文件,可以是鍵盤。
數(shù)據(jù)目的地可以是文件、顯示器或者其他設(shè)備。
而流只是在幫助數(shù)據(jù)進(jìn)行傳輸,并對傳輸?shù)臄?shù)據(jù)進(jìn)行處理,比如過濾處理.轉(zhuǎn)換處理等。
4.4.5字符流繼承結(jié)構(gòu)
4.4.6字節(jié)流繼承結(jié)構(gòu)
4.5File4.5.1File類
用來將文件或者文件夾封裝成對象方便對文件與文件夾進(jìn)行操作。
File對象可以作為參數(shù)傳遞給流的構(gòu)造函數(shù)。
了解File類中的常用方法以及跨平臺的分隔符separator。
4.5.2遞歸
函數(shù)自己調(diào)用自己。
注意:遞歸時(shí)一定要明確結(jié)束條件。應(yīng)用場景:
當(dāng)某一功能要重復(fù)使用時(shí)。練習(xí):
列出一個(gè)文件夾下所有的子文件夾以及子文件(遞歸調(diào)用,結(jié)束主要區(qū)分是文件夾還是文件)思考:
1,刪除一個(gè)目錄的過程是如何進(jìn)行的?(先把文件夾下的文件刪除在把文件夾刪除)2,復(fù)制一個(gè)目錄的過程呢?(不存在目錄就創(chuàng)建,否則遍歷文件夾,并復(fù)制文件)
4.6IO中的其他類
操作基本數(shù)據(jù)類型
DataInputStream與DataOutputStream操作字節(jié)數(shù)組
ByteArrayInputStream與ByteArrayOutputStream操作字符數(shù)組
CharArrayReader與CharArrayWrite操作字符串
StringReader與StringWriter
4.7其它流4.7.1打印流
PrintWriter與PrintStream
這兩個(gè)打印流的構(gòu)造函數(shù)可以接收的類型。文件的字符串路徑。String文件對象。File
字節(jié)輸出流。InputStream
對于PrintWriter因?yàn)槭亲址鳎可以接收字符輸出流。Writer對于字符串路徑和文件對象,可以指定字符集參數(shù)。對于字節(jié)輸出流和字符輸出流,可以接收自動(dòng)刷新參數(shù)。
注意:該布爾型參數(shù)為true,對于println,printf,format三個(gè)方法進(jìn)行自動(dòng)刷新。
4.7.2序列流
SequenceInputStream
構(gòu)造函數(shù):
SequenceInputStream(Enumerationen)
SequenceInputStream(InputStrreama,InputStreamb)作用:可以對兩個(gè)或者兩個(gè)以上的流進(jìn)行合并應(yīng)用:可以用于將多個(gè)文件合并成一個(gè)文件。
4.8字符編碼4.8.1概述
字符流的出現(xiàn)為了方便操作字符。更重要是的加入了編碼轉(zhuǎn)換。通過子類轉(zhuǎn)換流來完成。InputStreamReaderOutputStreamWriter
在兩個(gè)對象進(jìn)行構(gòu)造的時(shí)候可以加入字符集
4.8.2編碼表由來
計(jì)算機(jī)只能識別二進(jìn)制數(shù)據(jù),早期由來是電信號。為了方便應(yīng)用計(jì)算機(jī),讓它可以識別各個(gè)國家的文字。就將各個(gè)國家的文字用數(shù)字來表示,并一一對應(yīng),形成一張表。這就是編碼表。
4.8.3常見編碼表
ASCII:美國標(biāo)準(zhǔn)信息交換碼。
用一個(gè)字節(jié)的7位可以表示。ISO8859-1:拉丁碼表。歐洲碼表
用一個(gè)字節(jié)的8位表示。GB2312:中國的中文編碼表。
GBK:中國的中文編碼表升級,融合了更多的中文文字符號。Unicode:國際標(biāo)準(zhǔn)碼,融合了多種文字。
所有文字都用兩個(gè)字節(jié)來表示,Java語言使用的就是unicodeUTF-8:最多用三個(gè)字節(jié)來表示一個(gè)字符。
4.8.4轉(zhuǎn)換流的編碼應(yīng)用
可以將字符以指定編碼格式存儲。可以對文本數(shù)據(jù)指定編碼格式來解讀。指定編碼表的動(dòng)作由構(gòu)造函數(shù)完成。例程:
將“你好”兩個(gè)字符查指定的utf-8的碼表,獲取對應(yīng)的數(shù)字,并寫入到text.txt文件中。
OutputStreamWriterosw=newOutputStreamWriter(newFileOutputStream(“text.txt”),”utf-8);osw.write(“你好”);osw.close();
讀取硬盤上的文件數(shù)據(jù),將獲取到的數(shù)據(jù)查指定utf-8的碼表來解析該數(shù)據(jù)。InputStreamReaderisr=newInputStreamReader(newFileInputStream(“text.txt”),”utf-8);char[]buf=newchar[10];intnum=isr.read(buf);
Strings=newString(buf,0,num);System.out.println(s);
傳入編碼表的方法都會拋出不支持編碼異常(UnsupportedEncodingException);
4.8.5字符編碼
編碼:字符串字節(jié)數(shù)組解碼:字節(jié)數(shù)組字符串
原則:編錯(cuò)了,無解;編對了,解錯(cuò)了,可解。
5、網(wǎng)絡(luò)編程
5.1概述5.1.1網(wǎng)絡(luò)模型
OSI參考模型和TCP/IP參考模型
5.1.2網(wǎng)絡(luò)通訊要素
(1)IP地址
網(wǎng)絡(luò)中設(shè)備的標(biāo)識不易記憶,可用主機(jī)名
本地回環(huán)地址:127.0.0.1主機(jī)名:localhost(2)端口號
用于標(biāo)識進(jìn)程的邏輯地址,不同進(jìn)程的標(biāo)識
有效端口:0~65535,其中0~1024系統(tǒng)使用或保留端口。(3)傳輸協(xié)議
通訊的規(guī)則
常見協(xié)議:TCP(可靠連接),UDP(非可靠連接)
5.2TCP和UDP5.2.1UDP
將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接每個(gè)數(shù)據(jù)報(bào)的大小在限制在64k內(nèi)因無連接,是不可靠協(xié)議不需要建立連接,速度快
5.2.2TCP
建立連接,形成傳輸數(shù)據(jù)的通道。在連接中進(jìn)行大數(shù)據(jù)量傳輸
通過三次握手完成連接,是可靠協(xié)議(詳見->3.3.2)必須建立連接,效率會稍低
5.3Socket5.3.1Socket概述
Socket就是為網(wǎng)絡(luò)服務(wù)提供的一種機(jī)制。通信的兩端都有Socket。
網(wǎng)絡(luò)通信其實(shí)就是Socket間的通信。數(shù)據(jù)在兩個(gè)Socket間通過IO傳輸。
5.3.2UDP傳輸
DatagramSocket與DatagramPacket建立發(fā)送端,接收端。建立數(shù)據(jù)包。
調(diào)用Socket的發(fā)送接收方法。關(guān)閉Socket。
發(fā)送端與接收端是兩個(gè)獨(dú)立的運(yùn)行程序。發(fā)送端:
在發(fā)送端,要在數(shù)據(jù)包對象中明確目的地IP及端口。DatagramSocketds=newDatagramSocket();byte[]by=“hello,udp”.getBytes();DatagramPacketdp=newDatagramPacket(by,0,by.length,InetAddress.getByName(“127.0.0.1”),10000);ds.send(dp);ds.close();接收端:
在接收端,要指定監(jiān)聽的端口:
DatagramSocketds=newDatagramSocket(10000);byte[]by=newbyte[1024];DatagramPacketdp=newDatagramPacket(by,by.length);ds.receive(dp);Stringstr=newString(dp.getData(),0,dp.getLength());System.out.println(str+"--"+dp.getAddress());ds.close();
UDP聊天程序:
通過鍵盤錄入獲取要發(fā)送的信息。將發(fā)送和接收分別封裝到兩個(gè)線程中。
5.3.3TCP傳輸
Socket和ServerSocket建立客戶端和服務(wù)器端
建立連接后,通過Socket中的IO流進(jìn)行數(shù)據(jù)的傳輸關(guān)閉socket
同樣,客戶端與服務(wù)器端是兩個(gè)獨(dú)立的應(yīng)用程序。
5.3.4Tcp傳輸最容易出現(xiàn)的問題
客戶端連接上服務(wù)端,兩端都在等待,沒有任何數(shù)據(jù)傳輸。通過例程分析:
因?yàn)閞ead方法或者readLine方法是阻塞式。解決辦法:自定義結(jié)束標(biāo)記
使用shutdownInput,shutdownOutput方法。
5.4示例5.4.1示例程序一
說明:網(wǎng)絡(luò)的運(yùn)用
*對于這部分的程序,必須注意:
*必須服務(wù)端和客戶端一起編譯運(yùn)行才能測試程序.通常Server代表服務(wù)端Client代表客戶端
*部分運(yùn)用到io流的概念,可以通過前面的筆記配合復(fù)習(xí)
*該程序是簡單的通訊和客戶端發(fā)送功能的演示.
*注意的地方是Socket是客戶端的類ServerSocket是服務(wù)端的類
*服務(wù)端創(chuàng)建了接收端口.同樣,客戶端也必須發(fā)送相對應(yīng)的端口和服務(wù)器的IP.
*這個(gè)時(shí)候,服務(wù)端利用服務(wù)端里面的Socket類定義accept監(jiān)聽的方法,他負(fù)責(zé)監(jiān)聽客戶端的IP和端口的發(fā)送
*我們可以在服務(wù)端用一句打印輸出來判定客戶端是否鏈接上.
*由于客戶端鏈接上后,確定能發(fā)送數(shù)據(jù).所以必須利用客戶端的一個(gè)方法getOutputStream.
*同樣,我們把該套接字外面套上管道,用writeUTF方法發(fā)送.
*為了確定能接收到客戶端的信息,服務(wù)端必須同樣建立getInputStream方法,同時(shí)也包上管道,利用readUTF方法等待接收*就此所有通訊代碼完成*/
客戶端:TCPClient.java
importjava.net.*;importjava.io.*;publicclassTCPClient{publicstaticvoidmain(String[]args)throwsException{Sockets=newSocket("127.0.0.1",6611);//發(fā)送的地址和端口OutputStreamos=s.getOutputStream();//返回此套接字的輸出流。DataOutputStreamdos=newDataOutputStream(os);//建立管道輸出dos.writeUTF("客戶端發(fā)送給服務(wù)器數(shù)據(jù)");//以utf-8為了省空間輸入dos.flush();dos.close();s.close();}}
服務(wù)端:TCPServer.java
importjava.net.*;importjava.io.*;publicclassTCPServer{publicstaticvoidmain(String[]args)throwsException{ServerSocketss=newServerSocket(6611);//接收的地址和端口while(true){//相當(dāng)于分配好的端口,后面有個(gè)監(jiān)聽器,在兩個(gè)之間有個(gè)插座,當(dāng)端口和插座連上,就通知監(jiān)聽端Sockets=ss.accept();//偵聽并接受到此套接字的連接。此方法在連接傳入之前一直阻塞。//這個(gè)是服務(wù)端特有的監(jiān)聽客戶端的一個(gè)方法,他必須死循環(huán),應(yīng)為他不知道有多少客戶端要連他,只能是有一個(gè)客戶端連他,他就accept監(jiān)聽一次//如果沒有客戶端鏈接,就一直等待。。。。直到鏈接就給監(jiān)聽方法,然后繼續(xù)等待。。System.out.println("客戶端鏈接成功!");//這段話是測試客戶端是否鏈接上服務(wù)端//返回此套接字的輸入流
DataInputStreamdis=newDataInputStream(s.getInputStream());//建立輸入管道System.out.println(dis.readUTF());//這個(gè)也是阻塞方式的,必須等對方寫東西過來dis.close();s.close();//關(guān)閉此套接字}}}5.4.2示例程序二
客戶端:TestSocketClient.java
importjava.net.*;importjava.io.*;publicclassTestSockClient{publicstaticvoidmain(String[]args){InputStreamis=null;OutputStreamos=null;try{Socketsocket=newSocket("localhost",5888);//創(chuàng)建發(fā)送地址端口is=socket.getInputStream();//定義輸入套接字os=socket.getOutputStream();//定義輸出套接字DataInputStreamdis=newDataInputStream(is);//包裝管道DataOutputStreamdos=newDataOutputStream(os);dos.writeUTF("客戶端");//客戶端程序要先寫,和服務(wù)端先讀保持一致Strings=null;if((s=dis.readUTF())!=null);//等客戶端寫完就要開始讀服務(wù)端的了,應(yīng)為服務(wù)端開始寫了System.out.println(s);//輸出服務(wù)端的數(shù)據(jù)dos.close();dis.close();socket.close();}catch(UnknownHostExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}
服務(wù)端:TestSocketServer.java/****tcp網(wǎng)絡(luò)同樣可以相互發(fā)送.*/
importjava.io.*;importjava.net.*;publicclassTestSockServer{publicstaticvoidmain(String[]args){InputStreamin=null;OutputStreamout=null;try{ServerSocketss=newServerSocket(5888);//服務(wù)器定義端口Socketsocket=ss.accept();//第一監(jiān)聽端in=socket.getInputStream();//定義輸入套接字out=socket.getOutputStream();//定義輸出套接字DataOutputStreamdos=newDataOutputStream(out);//包裝管道DataInputStreamdis=newDataInputStream(in);//包裝管道Strings=null;if((s=dis.readUTF())!=null){//這里,服務(wù)端先等待讀客戶端的方法System.out.println(s);System.out.println("from:"+socket.getInetAddress());//獲取地址System.out.println("Port:"+socket.getPort());//獲取端口號.是隨機(jī)分配的}dos.writeUTF("你好,這里是服務(wù)端發(fā)送的數(shù)據(jù)");//結(jié)束讀之后開始寫dis.close();dos.close();socket.close();}catch(IOExceptione){e.printStackTrace();}}}
5.4.3示例程序三
說明:使用線程接收到請求,然后使用一個(gè)線程對應(yīng)于一個(gè)客戶端
客戶端:ChatClient.java
importjava.io.*;importjava.net.*;importjava.awt.*;importjava.awt.event.*;publicclassChatClientextendsFrame{TextAreata=newTextArea();
TextFieldtf=newTextField();publicvoidlaunchFrame()throwsException{this.add(ta,BorderLayout.CENTER);this.add(tf,BorderLayout.SOUTH);tf.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEventae){try{StringsSend=tf.getText();if(sSend.trim().length()==0)return;ChatClient.this.send(sSend);tf.setText("");ta.append(sSend+"\\n");}catch(Exceptione){e.printStackTrace();}}});this.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}});setBounds(300,300,300,400);setVisible(true);tf.requestFocus();}Sockets=null;publicChatClient()throwsException{s=newSocket("127.0.0.1",8888);launchFrame();(newThread(newReceiveThread())).start();}
publicvoidsend(Stringstr)throwsException{DataOutputStreamdos=newDataOutputStream(s.getOutputStream());dos.writeUTF(str);}publicvoiddisconnect()throwsException{s.close();}publicstaticvoidmain(String[]args)throwsException{BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));ChatClientcc=newChatClient();Stringstr=br.readLine();while(str!=null&&str.length()!=0){cc.send(str);str=br.readLine();}cc.disconnect();}classReceiveThreadimplementsRunnable{publicvoidrun(){if(s==null)return;try{DataInputStreamdis=newDataInputStream(s.getInputStream());Stringstr=dis.readUTF();while(str!=null&&str.length()!=0){//System.out.println(str);ChatClient.this.ta.append(str+"\\n");str=dis.readUTF();}}catch(Exceptione){e.printStackTrace();
}}}}服務(wù)端:ChatServer.java
importjava.net.*;importjava.util.*;importjava.io.*;importjava.awt.*;importjava.awt.event.*;publicclassChatServerextendsFrame{TextAreata=newTextArea();publicvoidlaunchFrame(){add(ta,BorderLayout.CENTER);setBounds(0,0,200,300);this.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}});setVisible(true);}ServerSocketserver=null;CollectioncClient=newArrayList();publicChatServer(intport)throwsException{server=newServerSocket(port);launchFrame();}publicvoidstartServer()throwsException{
while(true){Sockets=server.accept();cClient.add(newClientConn(s));ta.append("NEW-CLIENT"+s.getInetAddress()+":"+s.getPort());ta.append("\\n"+"CLIENTS-COUNT:"+cClient.size()+"\\n\\n");}}classClientConnimplementsRunnable{Sockets=null;publicClientConn(Sockets){this.s=s;(newThread(this)).start();}publicvoidsend(Stringstr)throwsIOException{DataOutputStreamdos=newDataOutputStream(s.getOutputStream());dos.writeUTF(str);}publicvoiddispose(){try{if(s!=null)s.close();cClient.remove(this);ta.append("Aclientout!\\n");ta.append("CLIENT-COUNT:"+cClient.size()+"\\n\\n");}catch(Exceptione){e.printStackTrace();}}publicvoidrun(){try{DataInputStreamdis=newDataInputStream(s.getInputStream());Stringstr=dis.readUTF();
}while(str!=null&&str.length()!=0){System.out.println(str);for(Iteratorit=cClient.iterator();it.hasNext();){ClientConncc=(ClientConn)it.next();if(this!=cc){cc.send(str);}}str=dis.readUTF();//send(str);}this.dispose();}catch(Exceptione){System.out.println("clientquit");this.dispose();}}}publicstaticvoidmain(String[]args)throwsException{ChatServercs=newChatServer(8888);cs.startServer();}6、Servlet
6.1Servlet基礎(chǔ)6.1.1什么是Servlet
Servlet是一種用Java語言編寫的Web應(yīng)用組件
Servlet主要用于動(dòng)態(tài)網(wǎng)頁輸出,擴(kuò)展了Web服務(wù)器的功能Servlet由Servlet容器進(jìn)行管理
6.1.2Servlet的優(yōu)點(diǎn)
(1)可移植性高:
可在不同的操作系統(tǒng)平臺和不同應(yīng)用服務(wù)器平臺下移植。(2)功能強(qiáng)大:
Servlet可以使用JavaAPI核心的所有功能包括Web訪問、圖像處理、多線程、JDBC等。(3)模塊化:
每一個(gè)Servlet可以執(zhí)行一個(gè)特定的任務(wù),并且可以將它們并在一起工作,Serlvet之間是可以通信的。(4)高效持久:
Serlvet一旦載入,就駐留在內(nèi)存中,用線程的方式加快了響應(yīng)的速度。
6.1.3Servlet缺點(diǎn)
和傳統(tǒng)的CGI方式相同,JavaServlet也是利用輸出HTML語句來實(shí)現(xiàn)動(dòng)態(tài)網(wǎng)頁的,如果用它來開發(fā)整個(gè)網(wǎng)站,動(dòng)態(tài)部分和靜態(tài)頁面的整合過程將變得無法想象。這就是SUN還要推出JSP的原因。
6.1.4Servlet示例
publicclassServletExampleimplementsServlet{privateServletConfigconfig;privateStringencoding;@Overridepublicvoidinit(ServletConfigconfig)throwsServletException{//這個(gè)方法只會執(zhí)行一次//如果在web.xml文件中你設(shè)置了//級別大于0//那么就會在這個(gè)web應(yīng)用啟動(dòng)的時(shí)候就初始化,也就是調(diào)用這個(gè)方法
}//初始化方法,你可以在這里獲取初始化的參數(shù),如果你在配置該servlet的時(shí)候使用了參數(shù)Stringencoding=config.getInitParameter("encoding");System.out.println("Encodingis:------>"+encoding);//在初始化的時(shí)候你可以把ServletConfig保存下來,以便以后使用this.config=config;this.encoding=encoding;}@OverridepublicServletConfiggetServletConfig(){returnthis.config;}@Overridepublicvoidservice(ServletRequestrequest,ServletResponseresponse)throwsServletException,IOException{//這里是主要的業(yè)務(wù)邏輯處理,這里演示輸出編碼System.out.println("Theencodingis:------------>"+this.encoding);}@OverridepublicStringgetServletInfo(){returnnull;}@Overridepublicvoiddestroy(){//銷毀}
6.1.5Servlet注冊和運(yùn)行
Servlet程序必須通過Servlet容器來啟動(dòng)運(yùn)行,并且儲存目錄有特殊要求,通常需要存儲在\\WEB-INF\\classes\\目錄中。
Servlet程序必須在WEB應(yīng)用程序的web.xml文件中進(jìn)行注冊和映射其訪問路徑,才可以被Servlet引擎加載和被外界訪問。
一個(gè)元素用于注冊一個(gè)Servlet,它包含有兩個(gè)主要的子元素:和,分別用于設(shè)置Servlet的注冊名稱和Servlet的完整類名。
一個(gè)元素用于映射一個(gè)已注冊的Servlet的一個(gè)對外訪問路徑,它包含有兩個(gè)子元素:和,分別用于指定Servlet的注冊名稱和Servlet的對外訪問路徑.
6.1.6Servlet映射細(xì)節(jié)
同一個(gè)Servlet可以被映射到多個(gè)URL上,即多個(gè)元素的子元素的設(shè)置值可以是同一個(gè)Servlet的注冊名。
在Servlet映射到的URL中也可以使用*通配符,但是只能有兩種固定的格式:一種格式是“*.擴(kuò)展名”,另一種格式是以正斜杠(/)開頭并以“/*”結(jié)尾。
6.1.7默認(rèn)Servlet
如果某個(gè)Servlet的映射路徑僅僅為一個(gè)正斜杠(/),那么這個(gè)Servlet就成為當(dāng)前Web
應(yīng)用程序的缺省Servlet。
凡是在web.xml文件中找不到匹配的元素的URL,它們的訪問請求都將交給缺省Servlet處理,也就是說,缺省Servlet用于處理所有其他Servlet都不處理的訪問請求。
在\\conf\\web.xml文件中,注冊了一個(gè)名稱為org.apache.catalina.servlets.DefaultServlet的Servlet,并將這個(gè)Servlet設(shè)置為了缺省Servlet。當(dāng)訪問Tomcat服務(wù)器中的某個(gè)靜態(tài)HTML文件和圖片時(shí),實(shí)際上是在訪問這個(gè)缺省Servlet。
6.2Servlet詳解6.2.1Servlet的API包
JavaServletAPI包中提供的類和接口是用于完成客戶端與Servlet對象的交互,主要由兩個(gè)Java包組成:javax.servlet和javax.servlet.http.
在javax.servlet包中定義了所有的Servlet類都必須實(shí)現(xiàn)或擴(kuò)展的通用接口和類。在javax.servlet.http包中除了實(shí)現(xiàn)servlet包中的基本功能外還特別針對于HTTP協(xié)議定義了HttpServlet類。
ServletAPI的框架的核心是javax.servlet.Servlet接口,所有的Servlet都必須實(shí)現(xiàn)這一接口。
在Servlet接口中定義了5個(gè)方法,其中有3方法代表了Servlet的生命周期:init方法,負(fù)責(zé)初始化Servlet對象service方法,負(fù)責(zé)響應(yīng)客戶的請求
destroy方法,當(dāng)Servlet對象退出生命周期時(shí),負(fù)責(zé)釋放占用的資源
友情提示:本文中關(guān)于《java學(xué)習(xí)總結(jié)(基礎(chǔ)加web)》給出的范例僅供您參考拓展思維使用,java學(xué)習(xí)總結(jié)(基礎(chǔ)加web):該篇文章建議您自主創(chuàng)作。
來源:網(wǎng)絡(luò)整理 免責(zé)聲明:本文僅限學(xué)習(xí)分享,如產(chǎn)生版權(quán)問題,請聯(lián)系我們及時(shí)刪除。