1. 程式人生 > 其它 >JavaSE02_Day04(下)-自定義空請求異常、XML解析(定義、格式、作用、解析方案及案例演示)

JavaSE02_Day04(下)-自定義空請求異常、XML解析(定義、格式、作用、解析方案及案例演示)

一、WebServer專案

1.1 版本七:自定義異常來解決空請求問題

  Http協議允許客戶端傳送一個空請求,也就是客戶端與服務端斷開連線的時候,實際上並沒有傳送任何的內容,但是我們所書寫的程式碼是要對請求進行解析,那麼這就會導致解析產生異常,不能正確的拆分出三部分內容。當我們解析請求的時候,如果發現發過來的是一個空請求,我們將異常最終拋給ClientHandler類,並且ClientHandler在接收這個異常後就不做任何的處理,直接斷開連線。

步驟1:在http包下自定義一個異常類EmptyRequestException(空請求異常)

package cn.tedu.http;
/**
* 自定義異常類
* 用於解決瀏覽器傳送空請求問題
* @author cjn
*
*/
public class EmptyRequestException extends Exception{
/**
* Java的序列化機制是通過在執行時判斷類的serialVersionUID來驗證版本一致性的。
* 原因:在進行反序列化時,JVM會把傳來的位元組流中的serialVersionUID與本地實體
* 類中的serialVersionUID進行比較,如果相同則認為是一致的,便可以進行反序列化,
* 否則就會報序列化版本不一致的異常
*/
private static final long serialVersionUID = 1L;

/*
* source -> generate constructors from superClass
* 生成EmptyRequestException類的構造器,
* 並且把過載的構造器一併都生成,
* 在構造器的內部呼叫超類中的構造器方法
*/
public EmptyRequestException() {
super();
}

public EmptyRequestException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}

public EmptyRequestException(String message, Throwable cause) {
super(message, cause);
}

public EmptyRequestException(String message) {
super(message);
}

public EmptyRequestException(Throwable cause) {
super(cause);
}

}

步驟2:在HttpRequest類中進行請求行解析時,如果發現是一個空請求,那麼咱們直接丟擲自定義異常,並將其拋給構造方法,再經構造方法拋給ClientHandler類。

步驟3:在ClientHandler類中的run方法中新增一個空請求的異常捕獲,以達到當例項化HttpRequest出現空請求後,跳過其他所有處理操作的目的。

執行結果出現相關資訊:

二、XML解析

2.1 XML定義

  可擴充套件標記性語言eXtensible Markup Language

2.2 XML檔案格式

<?xml version="1.0" encoding="UTF-8"?>
<teachers>
<lecturer>&lt;蒼老師&gt;</lecturer>
<classteacher>小娜</classteacher>
<counselors>
<counselor>美麗</counselor>
<counselor>小紅</counselor>
<counselor>
<![CDATA[ 伏爾泰說過一<句著名的話,不>經巨大的困難,不會有偉大<>的事業。這啟發了我. 小白老師的發"生,到底"需要如何做到,不小白''老師的發生,又&會如何產生。]]>
</counselor>
</counselors>
</teachers>

2.3 作用

  使用XML可以進行對資料的儲存,也可以進行傳輸資料。

2.4 特殊字元

2.5 CDATA段

格式:< ! [CDATA [內容] ] >

作用:避免特殊字元讀取錯誤,可直接將內容方法CDATA[ ]中。

 <![CDATA[ 伏爾泰說過一<句著名的話,不>經巨大的困難,不會有偉大<>的事業。這啟發了我. 小白老師的發"生,到底"需要如何做到,不小白''老師的發生,又&會如何產生。]]>

2.6 XML解析

  獲取XML檔案中的內容

2.7 XML解析的方案

  • DOM:速度較慢,可以修改元素的內容;

  • SAX

    :速度較快,不可以修改元素的內容。

2.8 DOM4J的依賴匯入

下載jar包或複製程式碼:

<!-- dom4j 1.6.1 -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>

在pom.xml檔案中新增dom4j元件依賴:

注意:要加一對標籤<dependencies></dependencies>,新增後工具自動載入相關jar包

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.tedu</groupId>
<artifactId>webserver01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</project>

2.9 XML檔案解析案例

新建emp.xml檔案:

<?xml version="1.0" encoding="UTF-8"?>
<list>
<emp id="1">
<name>小瀋陽</name>
<age>36</age>
<gender>男</gender>
<sal>1200</sal>
</emp>
<emp id="2">
<name>趙四</name>
<age>38</age>
<gender>男</gender>
<sal>2200</sal>
</emp>
<emp id="3">
<name>宋小寶</name>
<age>33</age>
<gender>男</gender>
<sal>2500</sal>
</emp>
<emp id="4">
<name>劉能</name>
<age>31</age>
<gender>男</gender>
<sal>1800</sal>
</emp>
</list>

2.10 相關API

  • 獲取根節點: Element getRootElement();

  • 獲取當前標籤的所有子元素

    • List elements();

    • List elements(String name);//獲取指定標籤的子元素

  • 獲取標籤名稱 :String getName();

  • 獲取當前標籤中指定名字的子元素:Element element(String name)

  • 獲取標籤中的文字內容

    • String getText();

    • String elementText();//一般用這個

2.11 案例演示

package cn.tedu;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
* 使用DOM4J進行解析emp.xml檔案
* 需要將emp.xml檔案從磁碟中讀取到記憶體中,然後通過
* DOM4J所提供的相關API解析獲取的員工資訊,封裝到
* Emp員工物件中。最後再將每一個Emp員工物件新增到
* List集合中。
* @author cjn
*
*/
public class ParseXML {

public static void main(String[] args) {
/*
* 具體解析步驟:
* 1.需要建立SAXReader物件
* 2.使用SAXReader物件進行讀取emp.xml檔案,讀取完以後會返回一個Document文件物件
* 3.通過Document物件獲取XML檔案的根標籤<list></list>
* 4.通過根標籤進行獲取裡面的子標籤對應的元素內容
*/
try {
//1.建立SAXReader物件
SAXReader reader = new SAXReader();

//2.使用SAXReader物件進行讀取emp.xml檔案,讀取完以後會返回一個Document文件物件
//File file = new File("./emp.xml");//./寫不寫效果都是一樣的,都是相對於當前專案而言
File file = new File("emp.xml");
Document document = reader.read(file);
//或 Document document = reader.read(new File("emp.xml"));

//3.通過Document物件獲取XML檔案的根標籤<list></list>
//獲取根節點list節點元素
Element root = document.getRootElement();

//4.通過根標籤進行獲取裡面的子標籤對應的元素內容
//獲取根節點中名稱為emp節點元素
List<Element> emps = root.elements("emp");

//5.準備集合物件,用於儲存Emp員工物件
List<Emp> empList = new ArrayList<Emp>();

//遍歷emps集合中的所有emp節點元素
for (Element e : emps) {
//獲取emp節點元素中的子節點
//獲取姓名 按照方式一獲取元素對應的文字內容,先獲取指定元素,再通過該元素獲取文字內容
Element nameEle = e.element("name");//<name>小瀋陽</name>
String empName = nameEle.getText();//小瀋陽

//獲取年齡 按照方式二獲取指定元素的文字內容
int empAge = Integer.parseInt(e.elementText("age"));

//獲取性別
String empGender = e.elementText("gender");

//獲取工資
double empSal = Double.parseDouble(e.elementText("sal"));

//獲取根標籤的屬性id
String empId = e.attributeValue("id");
System.out.println(empId);

//建立Emp員工物件,封裝員工資訊
Emp empObj = new Emp(empName, empAge, empGender, empSal);
//將員工物件新增到集合中
empList.add(empObj);
}
System.out.println("XML解析完成");

//解析完成,遍歷集合物件檢視解析的內容
for (Emp emp : empList) {
System.out.println("姓名:" + emp.getName() + ",年齡:" + emp.getAge() +
",性別:" + emp.getGender() + ",工資:" + emp.getSalary());
}

} catch (DocumentException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

}

輸出結果

1
2
3
4
XML解析完成
姓名:小瀋陽,年齡:36,性別:男,工資:1200.0
姓名:趙四,年齡:38,性別:男,工資:2200.0
姓名:宋小寶,年齡:33,性別:男,工資:2500.0
姓名:劉能,年齡:31,性別:男,工資:1800.0