第三天:XML&反射

一、XML

1 什麼是XML

XML全稱爲Extensible Markup Language,意思是可擴展的標記語言。XML語法上和HTML比較相似,但HTML中的元素是固定的,而XML的標籤是可以由用戶自定義的

2、應用常見

<1>配置文件

32fdce3af8d729e60c445bfcf41ccce7.jpg

<2>存放數據

81169d7e52bb0f65074af825cfaa16ed.jpg

3、XML語法

<1>XML文檔聲明

19c29484c754bfbfd172aee04f6309f4.jpg

①文檔聲明必須爲<?xml開頭,以?>結束;

②文檔聲明必須從文檔的0行0列位置開始

③文檔聲明只有三個屬性

    a)version:指定XML文檔版本。必須屬性,因爲我們不會選擇1.1,只會選擇1.0

    b)encoding:指定當前文檔度的編碼。可選屬性,默認值是utf-8

<2>元素element

2aecdc35c625f7222c2521c84e5c91a2.jpg

①元素是XML文檔中最重要的組成部分

②普通元素的結構開始標籤、元素體、結束標籤組成。例如:<hello>大家好</hello>

③元素體:元素體可以是元素,也可以是文本,例如:<b><a>你好</a></b>

④空元素:空元素只有開始標籤,而沒有結束標籤,但元素必須自己閉合,例如:<c/>

⑤元素命令:

    a)區分大小寫

    b)不能使用空格,不能使用冒號;

    c)不建議以XML、xml、Xml開頭

⑥格式化良好的XML文檔,必須只有一個根元素

<3>屬性

a999f9c6b9301f5bb999037b9a1ec70b.jpg

①屬性是元素的一部分,它必須出現在元素的開始標籤中

②屬性的定義格式:屬性名=屬性值,其中屬性值必須使用單引或雙引

③一個元素可以有0~N個屬性,但一個元素中不能出現同名屬性

④屬性名不能使用空格、冒號等特殊字符,且必須以字母開頭

<4>註釋

XML的註釋與HTML相同,即以“<!--”開始,以“-->”結束。註釋內容會被XML解析器忽略

<5>轉義字符

XML中的轉義字符與HTML一樣

因爲很多符號已經被XML文檔結構所使用,所以在元素體或屬性值中想使用這些符號就必須使用轉義字符,例如:“<”、“>”、“&”

2a4664f4c263f8bb3928495664d2a9fa.jpg

<6>CDATA區

4d9f85ec8dbc984ff2b35e89042aeb53.jpg

當大量的轉義字符出現在xml文件中時,會使xml文檔的可讀性大幅度降低。這時如果使用CDATA段就會好一些

在CDATA段中出現的“<”、“>”、“&”,都無需使用轉義字符,這可以提高xml文檔的可讀性

在CDATA段中不能包含“]]>”,即CDATA段的結束定界符


4、DTD約束

常見的xml約束:DTD、Schema

<1>什麼是DTD

DTD(Document Type Definition),文檔類型定義,用來約束XML文檔。規定XML文檔中元素的名稱,子元素的名稱及順序,元素的屬性等

<2>DTD重點

開發中,我們很少自己編寫DTD約束文檔,通常情況我們都是通過框架提供的DTD約束文檔,編寫對應的XML文檔。常見框架使用DTD約束有:struts2、hibernate等

通過提供的DTD“web-app_2_3.dtd”編寫XML

5b5c43a072b6bbe5f180ff44c7714e3d.jpg

<3>案列實現

①步驟1:創建web.xml,並將“web-app_2_3.dtd”拷貝相同目錄下

    3dc4d5f5ded09e61bf0a631965336271.jpg

②步驟2:從DTD文檔開始處,拷貝需要的“文檔聲明”

    36258b1f42f3685bdf326c2a340d1f76.jpg

③步驟3:完成xml內容編寫

89d9b48beb2183729b3405ec7e8ce5d9.jpg

1bdacb637a34e37756a9c74a276947c6.jpg

<4>DTD語法

①文檔申明

內部DTD,在XML文檔內部嵌入DTD,只對當前XML有效

75121c36af06c37d8a82bfc4ee0de109.jpg

外部DTD-本地DTD,DTD文檔在本地系統上,公司內部自己項目使用

6be55c214a6333736ff68f1832a5f0e9.jpg

外部DTD-公共DTD,DTD文檔在網絡上,一般都有框架提供

1ccb02503545ee8717d6d005fac6e3ba.jpg

②元素聲明

6f01de98e167a7ffc7044d9004b925db.jpg

實例

283c6de01568d3db00bdaaaf9c31af37.jpg

③屬性聲明

63ed536e8771288295c44dab395f824b.jpg

e54d49b328d1ee53e1100d0a2adf1320.jpg

實例

3664b60ca269a796a008ae9de8bb7037.jpg

5、Schema約束

<1>什麼是Schema

Schema是新的XML文檔約束

Schema要比DTD強大很多,是DTD替代者

Schema本身也是XML文檔,但Schema文檔的擴展名爲xsd,而不是xml

Schema功能更強大,數據類型更完善

Schema支持名稱空間

<2>Schema重點要求

與DTD一樣,要求可以通過Schema約束文檔編寫xml文檔。常見框架使用Schema的有:Spring等

通過提供“web-app_2_5.xsd”編寫xml文檔

63cb7303351a9d8da859fa13d0819b5d.jpg

f569d4774f35680e01148cda636212e2.jpg

c3efcf2705688b15bac3bfe896faef3f.jpg

3f3f16a6a1fdfe21a4772dc6784a7a5e.jpg

案例文檔中同一個“命令空間”分別使用“默認命令空間”和“顯示命令空間”進行引入,所以文檔中<schema>和<xsd:schema>作用一樣

c7ba19f6308a0bde0cbb3bf812b375b7.jpg

<3>案例實現

①步驟1:創建web.xml,並將“web-app_2_5.xsd”拷貝到同級目錄

    83e12103b47cf2a01febef0b0bca82a1.jpg

②步驟2:從xsd文檔中拷貝需要的“命令空間”

7242602c238d2b7855035369baf87627.jpg

③完成xml內容編寫

5e87cb320934cc135bd47bd16d07b234.jpg

d3c6b6b7df42066629871e1d6cf50b6e.jpg

<4>命令空間(語法)

①什麼是命令空間

如果一個XML文檔中使用多個Schema文件,而這些Schema文件定義了相同名稱的元素時就會出現名字衝突,這就像一個java文件中使用了import java.util.*和import java.sql.*時,在使用Date類時,那麼就不明確Date是哪個包下的Date了

名稱空間就是用來處理元素和屬性的名稱衝突問題,與java中的包是同一用途。如果每個元素和屬性都有自己的名稱空間,那麼就不會出現名字衝突問題,就像是每個類都有自己所在的包一樣,那麼類名就不會出現衝突

②約束文檔和XML關係

當W3C提出Schema約束規範時,就提供“官方約束文檔”。我們通過官方文檔,必須“自定義schema約束文檔”,開發中“自定義文檔”由框架編寫者提供,我們提供“自定義文檔”限定,編寫出自己的xml文檔

aa9f72e09d1eb65ed76e06a5d245f5a0.jpg

③聲明命令空間

bc3a47a7e4d26023d0cb5b609cd57e32.jpg

實例:web-app_2_5.xsd

5d490ea9ba8212e17eaee177ecb56e0d.jpg

實例:web.xml

c4459feff05c9b21bb33fd6c502640f4.jpg

④其他介紹

自定義約束:web-app_2_5.xsd

cb12299b76af5b6e8147145e10848489.jpg

xml文檔:web.xml

9f571c2ceabcdf39ae8593636ac14d22.jpg

綜合案例:

ebf3b7d380e67c7e05d01a5a4fec4f61.jpg

綜合案例目的是:一個“命令空間”必須在schemaLocation中有一個成對描述信息(名稱 路徑)

4a9b17e532597fc47a87fdb2774fc937.jpg

6、dom4j解析

<1>XML解析概述

當將數據存儲在XML後,我們就希望通過程序獲得XML的內容。如果我們使用java基礎所學習的IO知識是可以完成的,不過需要非常繁瑣的操作纔可以完成,且開發中會遇到不同的問題(只讀、讀寫)。人們爲不同問題提供不同的解析方式,並提交對應的解析器,方便開發人員操作XML

<2>解析方式和解析器

①開發中比較常見的解析方式有三種,如下

Ⅰ、DOM:要求解析器把整個XML文檔裝載到內存,並解析成一個Document對象

    a)優點:元素與元素之間保留結構關係,故可以進行增刪改查操作

    b)缺點:XML文檔過大,可能出現內存溢出現象

Ⅱ、SAX:是一種速度更快,更有效的方法。它逐行掃描文檔,一邊掃描一邊解析。並以事件驅動的方式     進行具體解析,每執行一行,都將觸發對應的事件

    a)優點:處理速度快,可以處理大文件

    b)缺點:只能讀,逐行後將釋放資源

Ⅲ、PULL:Android內置的XML解析方式,類似SAX

②解析器:就是根據不同的解析方式提供的具體實現。有的解析器操作過於繁瑣,爲了方便開發人員,有提供易於操作的解析開發包

7ff9f80d8090c4a165792f7df2de73fc.jpg

③常見的解析開發包:

a)JAXP:sun公司提供支持DOM和SAX開發包

b)JDom:dom4j兄弟

c)jsoup:一種處理HTML特定解析開發包

d)dom4j:比較常用的解析開發包,hibernate底層採用

<3>DOM解析原理及結構模型

XML DOM和HTML DOM類似,XML DOM將整個XML文檔加載到內存,生成一個DOM樹,並獲得一個Document對象,通過Document對象就可以對DOM進行操作

21971ef227882e0537fb61b04b3c9320.jpg

be9ce977a09d1f723ac069e0c7e4100e.jpg

DOM中的核心概念就是節點,在XML文檔中的元素、屬性、文本等,在DOM中都是節點

660d00157fe91e0553dc3ec4be424669.jpg

<4>API使用

如果需要使用dom4j,必須導入jar包

1df4d143fd9a95ca0e026278090fa230.jpg

dom4j必須使用核心類SaxReader加載xml文檔獲得Document,通過Document對象獲得文檔的根元素,然後就可以操作了

常用API如下:

①SaxReader對象

  a)read(...)加載執行xml文檔

②Document對象

  a)getRootElement()獲得根元素

③Element對象

  a) elements(...) 獲得指定名稱的所有子元素。可以不指定名稱

  b) element(...) 獲得指定名稱第一個子元素。可以不指定名稱

  c) getName() 獲得當前元素的元素名

  d) attributeValue(...) 獲得指定屬性名的屬性值

  e) elementText(...) 獲得指定名稱子元素的文本值

  f) getText() 獲得當前元素的文本內容

6fb579ac77bec732a762022568ea0e65.jpg

9d9193388babbb107f3386987bc03c9c.jpg

二、反射

1、什麼是反射

<1>JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一   個對象,都能夠調用它的任意一個方法和屬性

<2>使用反射,可以在運行時對類Class、構造方法Constructor、普通方法Method、字段Field進行操作

2、Class對象

<1>Class對象,是對class文件(字節碼文件)的描述對象

<2>獲得Class對象

    ①已知類的完整路徑名(字符串):Class.forName(...)

    ②已知類型:String.class,確定參數列表

    ③已知對象:obj.getClass()

<3>常用方法

    ①使用默認構造方法創建實例:newInstance()

3、Constructor對象

<1>Constructor對象,是構造方法的描述對象

<2>獲得構造方法

    ①公共的構造方法:Constructor<T> getConstructor(Class<?>...parameterTypes),可變參數用       於確定形式參數列表

    ②已經聲明的構造方法:

        Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes),獲得私有的構造

<3>實例化對象實例

    ①newInstance(Object...initargs),可變參數用於確定實際參數列表

4、Method對象

<1>Method對象,是普通方法的描述對象

<2>獲得方法:

    ①獲得公共方法:Method getMethod(String name,Class<?>...parameterTypes)通過方法name獲得       方法,可變參數爲方法的形參參數列表

    ②獲得聲明方法:Method getDeclaredMethod(String name,Class<?>...parameterType)方法操         作;

<3>執行指定方法:

    ①Object invoke(Object obj,Object...args)執行指定對象obj,指定方法,可變參數爲方法的實       際參數列表

5、Field對象

<1>Field對象,是字段的描述對象

<2>獲得方法

    ①所有字段:Field getField(String name),通過字段名稱

    ②聲明字段:Field getDeclaredField(String name)

<3>操作

    ①獲得內容:Object get(Object obj)

    ②設置內容:void set(Object obj,Object value),確定實例對象

5、案例實現

<1>準備工作

爲了模擬服務器程序,且可以同時存在多個類似程序。故提供接口,接口中有3個方法,我們人爲約定三個方法的調用順序

29c8e9fb84c243af70877d87968d0a15.jpg

再爲接口編寫實現類

378e88ef21fc669a6f11dee2c8f0e50d.jpg

8c1ce7a64ab599364382774c895cefdd.jpg

34687735081ea1f362df98975d3e85da.jpg

測試,創建實現類實例對象

3f11dbd5582101bb0bd9cb4a9f3d12e7.jpg

<2>反射執行

測試程序我們直接new HelloServlet,這種編程方式我們稱爲硬編碼,即代碼寫死了。爲了後期程序的可擴展,開發中通常使用實現類的全限定類名(cn.itcast.e_web.HelloMyServlet),通過反射加載字符串指定的類,並通過反射創建實例

c1f5743f531d62c9ea0977dc0968334a.jpg

b0ab2f8fe7a53b179aab619ab80ebcf3.jpg

<3>解析xml

使用反射我們已經可以創建對象的實例,此時我們使用的全限定類名,但程序是仍寫死了,我們將其配置到xml文檔中。

xml文檔內容

6718cb1f0f120899e7d0739ddf2221b0.jpg

解析實現

c4f02c3300fc19dcc48b30182efc27b9.jpg

08c7481ee41c781f9f0e5f19cf839a70.jpg

<4>模擬瀏覽器路徑

上面我們已經解析xml,不過我們獲得內容是固定的。我們希望如果用戶訪問的路徑是/hello,將執行cn.itcast_web.HelloMyServlet程序,如果訪問是/hello2,將執行cn.itcast.e_web.HelloMyServlet2程序。

在執行測試程序前(@Before),解析xml文件,將解析的結果存放在Map中,map中數據的格式爲:

路徑=實現類

1f0399ed66ec1b166f8c1819cb6e4e43.jpg

解析xml思路:先解析<servlet>,將結果存放map,name=class,然後再解析<servlet-mapping>

通過name獲得class,再將url=class存放到map,最後將name=class移除

5b7043784ad8a94b0f7612d148486072.jpg

250defbe7b61627b0aa9011667f631ed.jpg

模擬瀏覽器請求路徑,通過url從map獲得class,並使用反射執行實現類

d6220253e84623df7529da045410661b.jpg

f9f7b97960b5cc612103cd5d371f483a.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章