1. 程式人生 > >XML,tomcat-java web後臺知識簡單總結

XML,tomcat-java web後臺知識簡單總結

最近學了一段時間的 java web 後臺,所學內容主要為網上視訊,以及《深入分析 java web 技術內幕》一書,先總結一下 XML 和 tomcat 內容。

XML

Xml 檔案解讀

關於XML文件的xmlns、xmlns:xsi和xsi:schemaLocation
xmlns表示預設的Namespace。
xmlns:xsi表示使用xsi作為字首的Namespace,當然字首xsi需要在文件中宣告。
來自 https://my.oschina.net/itblog/blog/390001

標籤

一個標籤可以有多個屬性,每個屬性都有它自己的名稱和取值,例如:

<input name=“text”>

屬性值一定要用雙引號(”)或單引號(’)引起來
定義屬性必須遵循與標籤相同的命名規範
多學一招:在XML技術中,標籤屬性所代表的資訊,也可以被改成用子元素的形式來描述,例如:

<input>
        <name>text</name>
</input>

處理指令

處理指令,簡稱PI (processing instruction)。處理指令用來指揮解析引擎如何解析XML文件內容。

例如,在XML文件中可以使用xml-stylesheet指令,通知XML解析引擎,應用css檔案顯示xml文件內容。

<?xml-stylesheet type="text/css" href="1.css"?>

處理指令必須以“

XML 約束

在XML技術裡,可以編寫一個文件來約束一個XML文件的書寫規範,這稱之為XML約束。
常用的約束技術

XML DTD 
XML Schema

XML DTD

XML檔案使用 DOCTYPE 宣告語句來指明它所遵循的DTD檔案,DOCTYPE宣告語句有兩種形式:

當引用的檔案在本地時,採用如下方式:

<!DOCTYPE 文件根結點 SYSTEM "DTD檔案的URL">

例如:

<!DOCTYPE 書架 SYSTEM “book.dtd”>。

當引用的檔案是一個公共的檔案時,採用如下方式:

<!DOCTYPE 文件根結點 PUBLIC "DTD名稱" "DTD檔案的URL">

例如:

<!DOCTYPE web-app PUBLIC 
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

XML Schema

XML Schema 也是一種用於定義和描述 XML 文件結構與內容的模式語言,其出現是為了克服 DTD 的侷限性

XML Schema VS DTD:

XML Schema符合XML語法結構。 
DOM、SAX等XML API很容易解析出XML Schema文件中的內容。 
XML Schema對名稱空間支援得非常好。 
XML Schema比XML DTD支援更多的資料型別,並支援使用者自定義新的資料型別。 
XML Schema定義約束的能力非常強大,可以對XML例項文件作出細緻的語義限制。
XML Schema不能像DTD一樣定義實體,比DTD更復雜,但Xml Schema現在已是w3c組織的標準,它正逐步取代DTD。  

XML 解析

XML 解析方式分為兩種:dom 和 sax

dom:(Document Object Model, 即文件物件模型) 是 W3C 組織推薦的處理 XML 的一種方式。
sax: (Simple API for XML) 不是官方標準,但它是 XML 社群事實上的標準,幾乎所有的 XML 解析器都支援它。

XML解析器

Crimson、Xerces 、Aelfred2

XML解析開發包

Jaxp、Jdom、dom4j

JAXP

JAXP 開發包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包組成
在 javax.xml.parsers 包中,定義了幾個工廠類,程式設計師呼叫這些工廠類,可以得到對xml文件進行解析的 DOM 或 SAX 的解析器物件。

DOM

javax.xml.parsers 包中的DocumentBuilderFactory用於建立DOM模式的解析器物件 ,DocumentBuilderFactory是一個抽象工廠類,它不能直接例項化,但該類提供了一個newInstance方法,這個方法會根據本地平臺預設安裝的解析器,自動建立一個工廠的物件並返回。

呼叫 DocumentBuilderFactory.newInstance() 方法得到建立 DOM 解析器的工廠。

呼叫工廠物件的 newDocumentBuilder方法得到 DOM 解析器物件。

呼叫 DOM 解析器物件的 parse() 方法解析 XML 文件,得到代表整個文件的 Document 物件,進行可以利用DOM特性對整個XML文件進行操作了。

SAX

在使用 DOM 解析 XML 文件時,需要讀取整個 XML 文件,在記憶體中構架代表整個 DOM 樹的Doucment物件,從而再對XML文件進行操作。此種情況下,如果 XML 文件特別大,就會消耗計算機的大量記憶體,並且容易導致記憶體溢位。

SAX解析允許在讀取文件的時候,即對文件進行處理,而不必等到整個文件裝載完才會文件進行操作。

SAX採用事件處理的方式解析XML檔案,利用 SAX 解析 XML 文件,涉及兩個部分:解析器和事件處理器:
解析器可以使用JAXP的API建立,創建出SAX解析器後,就可以指定解析器去解析某個XML文件。
解析器採用SAX方式在解析某個XML文件時,它只要解析到XML文件的一個組成部分,都會去呼叫事件處理器的一個方法,解析器在呼叫事件處理器的方法時,會把當前解析到的xml檔案內容作為方法的引數傳遞給事件處理器。
事件處理器由程式設計師編寫,程式設計師通過事件處理器中方法的引數,就可以很輕鬆地得到sax解析器解析到的資料,從而可以決定如何對資料進行處理。

SAX 解析 XML 步驟
使用SAXParserFactory建立SAX解析工廠

SAXParserFactory spf = SAXParserFactory.newInstance();

通過SAX解析工廠得到解析器物件

SAXParser sp = spf.newSAXParser();

通過解析器物件得到一個XML的讀取器

XMLReader xmlReader = sp.getXMLReader();

設定讀取器的事件處理器

xmlReader.setContentHandler(new BookParserHandler());

解析xml檔案

xmlReader.parse("book.xml");

其他三種解析工具就不一一寫了,以後用到再學習。

tomcat

tomcat 版本和原始碼都是 apache-tomcat-9.0.0.M21

tomcat 容器模型

tomcat 以遠端除錯模式啟動

較新的版本

方法一:命令列中輸入

JPDA_OPTS="-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"
catalina.sh jpda start

其實直接輸入 catalina.bat jpda 帶的預設引數和上面是一樣的。要想改變預設引數,CMD 中輸入如下:

export JPDA_ADDRESS="8080"

其他引數修改:
JPDA_TRANSPORT: to specify JPDA transport used
JPDA_ADDRESS: to specify port for remote debugging
JPDA_SUSPEND: to specify if to suspend JVM after startup

方法二:修改 catalina.bat 檔案

舊版本

方法一:命令列中輸入

Set  “CATALINA_OPTS=-Xdebug  -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"
catalina.bat jpda

方法二:修改 catalina.bat 檔案

新增:Set  “CATALINA_OPTS=-Xdebug  -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"  
命令列視窗下輸入:
set JPDA_ADDRESS=8777(除錯埠) 
catalina.bat jpda start

引數說明:

-Xdebug                              : 啟用除錯模式

-Xrunjdwp<sub-options>  : 載入JVM的JPDA參考實現庫

transport=dt_socket           :Socket連線,可選dt_shmem 通過共享記憶體的方式連線到除錯伺服器

address=8000                     :除錯伺服器監聽的埠

server=y                             : 是否是伺服器端,n為客戶端

suspend=n                         : 啟動過程是否載入暫停,y為啟動時暫停,方便除錯啟動過程

啟動過程

類圖和時序圖如下:

server.xml檔案的載入

因為自己想看一下 tomcat 啟動時各種屬性是怎麼注入的,所以設定 JPDA_SUSPEND=”y”,然後再執行 catalina.bat jpda start

因為剛剛學了 XML 檔案的解析,就分析了一下啟動過程中 tomacat 是如何解析 server.xml 檔案的。

自己畫的類圖和時序圖如下:

時序圖只畫到了呼叫 startElement 函式,因為 SAX 採用事件處理的方式解析 XML 檔案,自己想看看這個過程是如何完成的。

Tomcat 類載入機制

原始碼中 Bootstrap main 方法呼叫自己的 init 方法,init 方法再呼叫自己的 initClassLoaders 方法,此方法內容如下,可以看出 tomcat 的類載入器有三個。

private void initClassLoaders() {
        try {
            commonLoader = createClassLoader("common", null);
            if( commonLoader == null ) {
                // no config file, default to this loader - we might be in a 'single' env.
                commonLoader=this.getClass().getClassLoader();
            }
            catalinaLoader = createClassLoader("server", commonLoader);
            sharedLoader = createClassLoader("shared", commonLoader);
        } catch (Throwable t) {
            handleThrowable(t);
            log.error("Class loader creation threw exception", t);
            System.exit(1);
        }
    }

tomcat生命週期的管理——生命週期統一介面Lifecycle

《深入分析 java web》一書中第11章講的很詳細,參考網頁中最下面的講的也很詳細。

有一點要注意的是,自己檢視的原始碼版本比較新,已經捨棄了 lifecyclesupport 類,listener 都是直接註冊到的各個容器中了的,沒有再經過統一管理。