[菜雞奶媽の專案實踐] 「疫情地圖」 —— 宣講會後的專案指導學習心得

2020-08-08 18:34:23

請結合電腦版右側的目錄閱讀

[菜雞奶媽の專案實踐]「疫情地圖」

前言

大三下學期期末,學校安排的宣講會後安排的專案練習,製作一個最終效果是一 個網頁版的中國「疫情地圖」,地圖中的疫情數據從另-一個網頁中獲取。
獲取數據的網頁:【點選進入】http://m.sinovision.net/newpneumonia.php
還在初學Python的菜雞奶媽突然意識到了對JAVA掌握的重要性和不足QAQ。

專案最終效果

三天的教學,主要以核心技術爲學習的重點,頁面、功能美化上有待改進。
在这里插入图片描述

專案步驟列表

由於專案結束和編寫學習心得之間隔了個10多天的參加計算機系統與程式設計競賽的複習,有些細節已經忘記了,需要重新看一遍專案教學的錄像才能 纔能想起來,所以這個專案步驟是逐步往下寫的時候再返回來新增的,不如把軟體的安裝也按照整個專案的操作順序來穿插進步驟裡。

  1. 安裝HBuilder X
  2. 編寫一個簡單的本地「疫情地圖」頁面(數據在.html內)
  3. Hbuilder X 執行到瀏覽器方法
  4. 新增地圖模組和本地疫情數據
  5. 本地數據網頁完整程式碼
  6. 安裝jdk, Eclipse, Tomcat
  7. 新建一個Eclipse專案
  8. 將HBuilder編寫的程式碼放入Eclipse
  9. 建立servlet後臺程式碼
  10. jquery實現ajax請求
  11. 使用jsoup模擬瀏覽器獲得數據
  12. 編寫 TestData.java 的內容
  13. io流實現數據儲存本地
  14. io流實現本地數據讀取到記憶體
  15. 使用jsoup解析html頁面
  16. 將獲取的數據發至前臺
  17. 修改html頁面的數據
  18. 後臺數據網頁完整程式碼
  19. 最終測試執行
  20. 專案完整程式碼(壓縮包)

具體步驟1:安裝HBuilder X

HBuilder是DCloud(數位天堂)推出的一款支援HTML5的Web開發IDE。 HBuilder的編寫用到了Java、C、Web和Ruby。HBuilder本身主體是由Java編寫。
它基於Eclipse,所以順其自然地相容了Eclipse的外掛。
快,是HBuilder的最大優勢,通過完整的語法提示和程式碼輸入法、程式碼塊等,大幅提升HTML、js、css的開發效率。

免費的,官網下載安裝即可 【下載地址】https://www.dcloud.io/hbuilderx.html
在这里插入图片描述

具體步驟2:編寫一個簡單的本地「疫情地圖」頁面(數據在.html內)

奶媽學的比較慢,而且容易忘,乾脆直接一步一步的把詳細操作寫出來把!!!

1. 開啓HBuilder,到空白介面

在这里插入图片描述

2. 新建一個專案(如:命名爲CSDN)

在这里插入图片描述
在这里插入图片描述

3. 建立後在專案的目錄位置會生成一個專案資料夾

在这里插入图片描述

4. 在CSDN專案內新建一個名爲"js"的目錄

在这里插入图片描述
在这里插入图片描述

5. 向js資料夾內匯入china.js、echarts.js、jquery.js檔案,可以選擇拖拽檔案或者複製貼上

在这里插入图片描述

三個.js檔案本來想直接複製到程式碼塊裡分享,結果發現地圖數據部分程式碼長度極長且有亂碼,但亂碼並不影響使用,所以還是放在了百度網盤裏分享,我設定的是永久有效,如果失效的話可以直接網上找同樣的檔名也能下載到。
鏈接: https://pan.baidu.com/s/1DxCZue6X6NQ5x_W0RPO86w 提取碼: wsyd

6. 在CSDN專案內新建一個.html檔案(如:命名爲yiqing.html)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7. 在CSDN專案匯入需要的圖片和其他附件

如: …\CSDN\1.png
在这里插入图片描述
在这里插入图片描述

8. 設計html頁面

在學校的主修課上還沒有講過html的知識,在大三上學期的百知教育講的一週的H5實訓課中第一次接觸html知識,之後就是靠自學。
推薦在菜鳥教學(www.runoob.com)上學習html知識 【點選開啓】 https://www.runoob.com/html/html-tutorial.html
爲了方便html初學者和日後忘記知識點,會將本次編寫html用到的知識點列出來。

HTML < style > type標籤("<>"內沒有空格)


HTML <style> type 屬性,type 屬性指示 <style></style> 標籤之間的內容。

在 HTML5 中, type 屬性不再是必須的。預設值爲 "text/css"<style type="text/css">
h1 {color:red;}
p {color:blue;}
</style>

h1、p 稱爲"標籤選擇器"

在这里插入图片描述

HTML class 屬性

HTML class 屬性,class 屬性定義了元素的類名。
class 屬性通常用於指向樣式表的類,它也可以用於 JavaScript 中來修改 HTML 元素的類名。

<element class="classname">

classname:規定元素的類的名稱。
如需爲一個元素規定多個類,用空格分隔類名。 
<span class="left important">. HTML 元素允許使用多個類。
名稱規則:
· 必須以字母 A-Z 或 a-z 開頭
· 可以是以下字元: (A-Za-z), 數位 (0-9), 橫桿 ("-"), 和 下劃線 ("_")
· 在 HTML 中, 類名是區分大小寫的

在这里插入图片描述

HTML id 屬性

id 屬性規定 HTML 元素的唯一的 id。
id 在 HTML 文件中必須是唯一的。
id 屬性可用作鏈接錨,通過 JavaScript 或通過 CSS 爲帶有指定 id 的元素改變或新增樣式。
在 HTML5 中, id 屬性可用於任何的 HTML 元素 (它會驗證任何HTML元素。但不一定是有用)。
id 定義時在 id 前有一個 # 。

<element id="id">

id:規定元素的唯一 id。
命名規則:
· 必須以字母 A-Z 或 a-z 開頭
· 其後的字元:字母(A-Za-z)、數位(0-9)、連字元("-")、下劃線("_")、冒號(":") 以及點號(".")
· 值對大小寫敏感

在这里插入图片描述

HTML < div > 標籤("<>"內沒有空格)

<div> 標籤定義 HTML 文件中的一個分隔區塊或者一個區域部分。
<div>標籤常用於組合塊級元素,以便通過 CSS 來對這些元素進行格式化。
提示:<div> 元素經常與 CSS 一起使用,用來佈局網頁。
註釋:預設情況下,瀏覽器通常會在 <div> 元素前後放置一個換行符,可以通過使用 CSS 改變這種情況。
HTML5 中不支援 align 屬性,請使用 CSS 的 text-align 替代。
CSS 語法: <div style="text-align:center">

在这里插入图片描述

編寫除了地圖模組的所有元素

下面 下麪的程式碼是除去地圖模組的所有html程式碼,語句的知識點可以從前面的屬性、標籤以及菜鳥教學(【點選開啓】https://www.runoob.com/html/html-tutorial.html)中找到,並且留出一個< div >框給地圖模組使用。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			.title{
				font-size: 40px;
				font-family: "微軟雅黑";
				color: red;
			}
			.subtitle{
				font-size: 25px;
				color: orange;
			}
			.jiange{
				height: 30px;
				border: 0px solid black;
			}
			#chinamap{
				height: 600px;
				width: 800px;
				border: 1px solid black;
			}
		</style>
	</head>
	<body><center>
		<img src="1.png" alt="標題圖片" width="800px" height="343px">
		<div class="title"><b>全國疫情數據統計地圖</b></div>
		<div class="jiange"></div>
		<div class="subtitle">萬衆一心 堅決打贏疫情防控阻擊戰</div>
		<div class="jiange"></div>
		<div id="chinamap">
			
		</div>
	</center></body>
</html>

具體步驟3:Hbuilder X 執行到瀏覽器方法

選單欄 → 執行 → 執行到瀏覽器 → 選擇瀏覽器
在这里插入图片描述
當前步驟執行效果圖
在这里插入图片描述

具體步驟4:新增地圖模組和本地疫情數據

1. 匯入相關的.js包

HTML < script > 標籤("<>"內沒有空格)

<script> 標籤用於定義用戶端指令碼,比如 JavaScript。
<script> 元素既可包含指令碼語句,也可以通過 "src" 屬性指向外部指令碼檔案。
JavaScript 通常用於影象操作、表單驗證以及動態內容更改。
|屬性		|值			|描述
|async		|async		|規定非同步執行指令碼(僅適用於外部指令碼)。
|charset	|charset	|規定在指令碼中使用的字元編碼(僅適用於外部指令碼)。
|defer		|defer		|規定當頁面已完成解析後,執行指令碼(僅適用於外部指令碼)。
|src		|URL		|規定外部指令碼的 URL。
|type		|MIME-type	|規定指令碼的 MIME 型別。

ECharts.js

(詳細教學可以瀏覽菜鳥教學【點選進入】https://www.runoob.com/echarts/echarts-tutorial.html)

ECharts 是一個使用 JavaScript 實現的開源視覺化庫,涵蓋各行業圖表,滿足各種需求。
ECharts 遵循 Apache-2.0 開源協定,免費商用。
ECharts 相容當前絕大部分瀏覽器(IE8/9/10/11,Chrome,Firefox,Safari等)及
相容多種裝置,可隨時隨地任性展示。
學習ECharts前需要有以下基礎:
	HTML 教學
	JavaScript 教學
ECharts 包含了以下特性:
· 豐富的視覺化型別
· 多種數據格式無需轉換直接使用
· 千萬數據的前端展現
· 行動端優化
· 多渲染方案,跨平臺使用
· 深度的互動式數據探索
· 多維數據的支援以及豐富的視覺編碼手段
· 動態數據
· 絢麗的特效
· 通過 GL 實現更多更強大絢麗的三維視覺化
· 無障礙存取(4.0+)

China.js

基於ECharts寫的中國地圖
在这里插入图片描述

jquery.js

(詳細教學可以瀏覽菜鳥教學【點選進入】https://www.runoob.com/jquery/jquery-tutorial.html)

jQuery 是一個 JavaScript 庫。
jQuery 極大地簡化了 JavaScript 程式設計。
jQuery 很容易學習。

按順序匯入.js包

ECharts.js 必須放在 China,js 的前面,否則地圖顯示不全

<script type="text/javascript" src="js/包名"></script>
(.html 檔案和 js 資料夾在同一目錄時)

匯入順序:

<script type="text/javascript" src="js/echarts.js"></script>
<script type="text/javascript" src="js/china.js"></script>
<script type="text/javascript" src="js/jquery.js"></script>

新增位置:
在这里插入图片描述

2. 在地圖id中定義一個函數並呼叫

JavaScript function 語句

function 語句用於宣告一個函數。
函數宣告後,我們可以在需要的時候呼叫。
在 JavaScript 中,函數是物件,函數也有屬性和方法。
函數也可以通過表達式定義。

定義一個initChinaMap()函數並呼叫

<div id="chinamap">
	<script>
		function initChinaMap() {}
		initChinaMap();  //呼叫上面定義的函數
	</script>		
</div>

新增位置:
在这里插入图片描述

3. 初始化Echarts範例

JavaScript var 語句

var 語句用於宣告變數。
JavaScript 變數的建立也叫作"宣告"一變數:

var varname;

變數宣告後,變數爲空 (沒有值)。
爲變數賦值,操作如下:

varname = value;

宣告變數時,同樣可以爲變數賦值:

var varname = value;

varname:
必須有,指定變數名,變數名可以包含字母,數位,下劃線和美元符號。
· 變數名必須以字母開頭
· 變數名也可以以$和_開頭(但一般不這麼用)
· 變數名是大小寫敏感的(y和Y是不同的變數)
· 保留字(如JavaScript關鍵字)不能作爲變數名使用
value:
可選,指定變數的值。
注意:如果變數宣告未指定值,其預設值爲 undefined

HTML DOM getElementById() 方法

getElementById() 方法可返回對擁有指定 ID 的第一個物件的參照。
HTML DOM 定義了多種查詢元素的方法,除了 getElementById() 之外,
還有 getElementsByName() 和 getElementsByTagName()。
如果沒有指定 ID 的元素返回 null。
如果存在多個指定 ID 的元素則返回第一個。
如果需要查詢到那些沒有 ID 的元素,你可以考慮通過CSS選擇器使用 querySelector()。

document.getElementById(elementID)

elementID:
必須有,元素ID屬性值,型別爲 String
返回值:
元素物件,指定ID的元素

ECharts 非同步載入數據(ECharts.setOption)

ECharts 通常數據設定在 setOption 中,如果我們需要非同步載入數據,
可以配合 jQuery 等工具,在非同步獲取數據後通過 setOption 填入數據和設定項就行。

例:初始化一個 ECharts 範例名爲 myEChart,已定義一個設定項名爲 optionMap,
使用制定的設定項和數據顯示圖表。

myChart.setOption(optionMap);

初始化 ECharts 方法

// 初始化echarts範例
var echartName = echarts.init(document.getElementById(id));

在函數結尾初始化Echarts範例並顯示圖表

Echarts 範例命名爲 myChart,設定項命名爲 optionMap

// 初始化Echarts範例
var myChart = echarts.init(document.getElementById('chinamap'));  // id = chinamap
// 使用制定的設定項和數據顯示圖表
myChart.setOption(optionMap);

新增位置:
在这里插入图片描述

4. 定義ECharts範例設定項(optionMap)

在 .setOption 前定義一個 var 設定

var optionMap = {};  // var 變數,語句後面有分號";"

新增位置:
在这里插入图片描述

5. ECharts範例的設定項資訊(項內固定變數名)

backgroundColor 背景顏色

Style backgroundColor 屬性:
backgroundColor 屬性設定或返回元素的背景顏色。
設定 backgroundColor 屬性:

element.style.backgroundColor="color|inherit|transparent"

返回 backgroundColor 屬性:

element.style.backgroundColor

|color			|規定背景顏色。在 CSS 顏色值中尋找可能的顏色值的完整列表。
|inherit		|背景顏色從父元素繼承。
|transparent	|預設。背景顏色是透明的(基本內容將會穿透)。
預設值:transparent
返回值:一個代表背景顏色的字串

tooltip 提示工具,tigger() 方法

jQuery Tooltip:
jQuery Tooltip 外掛取代了原生的工具提示框,可自定義,只需要調整它們的內容、位置和外觀即可。
推薦使用 jQuery UI 工具提示框(Tooltip)。
jQuery trigger() 方法:
trigger() 方法觸發被選元素上指定的事件以及事件的預設行爲(比如表單提交)。
該方法與 triggerHandler() 方法類似,不同的是 triggerHandler() 不觸發事件的預設行爲。
與 triggerHandler() 方法相比的不同之處:
· trigger() 方法不會引起事件(比如表單提交)的預設行爲
· trigger() 會操作 jQuery 物件匹配的所有元素,而 triggerHandler() 隻影響第一個匹配元素。
· 由 triggerHandler() 建立的事件不會在 DOM 樹中冒泡,如果目標元素不直接處理,則不會發生變化。

series 設定屬性

ECharts 的設定列表。
這裏列出該專案需要的屬性:
name:屬性的名稱,如「確診病例」(將省份名稱視爲 data 數據中的 nametype:optionMap 的圖表型別
mapType:地圖型別
data:每個省份塊的數據,一般爲 {name, value}
label:省份塊的標籤
:{
	normal:常規設定
	:{
		show:常規時省份塊上的名稱顯示(true/false)
	},
	emphsis:滑鼠移動到位置時名稱的高亮樣式設定
	:{
		show:指向時省份塊上的名稱高亮顯示(true/false)
		color:高亮時名稱的顏色
	}
}

6. 新增範例設定項資訊(mydata爲空)

設定項資訊(在之前定義一個 var 變數 mydata):

var mydata;
var optionMap = {
	backgroundColor: 'white',
	//提示工具(在滑鼠移動到指定元素後觸發)
	tooltip:{
		trigger:'item'
	},
	//設定屬性
	series: {
		name: '確診病例',
		type: 'map',
		mapType: 'china',  //地圖型別
		data: mydata,  //疫情數據{name, value}
		label:{
			normal:{
			show: true  //省份名稱
		},
		emphasis:{  //高亮樣式
			show: true,
			color: 'red'  //高亮時省份名的顏色
		}
	}					
}

新增位置:
在这里插入图片描述

執行截圖

此時滑鼠放在省份塊上不會顯示資訊。
在这里插入图片描述

7. 定義原生的地圖省份數據(mydata)

在設定屬性 series 中的 data 變數需要賦值一個數組,在製作本地數據的網頁時可以先匯入原生的數據進行試驗,偵錯成功後可以嘗試將本地數據變爲從其他網站上獲取的數據。
使用臨時的數據進行測試:

var mydata = [{name: '北京',value: '253' },{name: '天津',value: '69' },
			{name: '上海',value: '334' },{name: '重慶',value: '560' },
			{name: '河北',value: '135' },{name: '河南',value: '1010' },
			{name: '雲南',value: '124' },{name: '遼寧',value: '121' },
			{name: '黑龍江',value: '190' },{name: '湖南',value: '661' },
			{name: '安徽',value: '987' },{name: '山東',value: '307' },
			{name: '新疆',value: '99' },{name: '江蘇',value: '631' },
			{name: '浙江',value: '895' },{name: '江西',value: '548' },
			{name: '湖北',value: '62031' },{name: '廣西',value: '150' },
			{name: '甘肅',value: '57' },{name: '山西',value: '81' },
			{name: '內蒙古',value: '42' },{name: '陝西',value: '165' },
			{name: '吉林',value: '54' },{name: '福建',value: '205' },
			{name: '貴州',value: '64' },{name: '廣東',value: '1332' },
			{name: '青海',value: '17' },{name: '西藏',value: '1' },
			{name: '四川',value: '301' },{name: '寧夏',value: '34' },
			{name: '海南',value: '99' },{name: '臺灣',value: '99' },
			{name: '香港',value: '21' },{name: '澳門',value: '10' }];

新增位置:
在这里插入图片描述

執行截圖

此時滑鼠放在省份塊上會顯示 series.name、name、value。
在这里插入图片描述

8. 在設定項中新增視覺對映(optionMap)

ECharts 數據的視覺對映(visualMap)

ECharts 數據的視覺對映:
數據視覺化簡單來講就是將數據用圖表的形式來展示,專業的表達方式就是數據到視覺元素的對映過程。
ECharts 的每種圖表本身就內建了這種對映過程,我們之前學習到的柱形圖就是將數據對映到長度。
此外,ECharts 還提供了 visualMap 元件 來提供通用的視覺對映。
visualMap 元件中可以使用的視覺元素有:
· 圖形類別(symbol)
· 圖形大小(symbolSize)
· 顏色(color)
· 透明度(opacity)
· 顏色透明度(colorAlpha)
· 顏色明暗度(colorLightness)
· 顏色飽和度(colorSaturation)
· 色調(colorHue)

該專案中使用的 visualMap 屬性:

visualMap:視覺對映,包含比例尺和省份塊的顏色
:{
	left:比例尺的左右方向(left/right/middle)
	top:比例尺的豎直方向(top/up/bottom/middle)
	splitList:分割陣列的列表
	color:分割後各陣列的顏色,顏色數量小於陣列數量時,中間顏色平均分配
	show:顯示比例尺(true/false)
}

定義比例尺陣列(splitList)

在 optionMap 外定義一個 var 變數的陣列(例:命名爲 splitList1)

var splitList1 = [
	{start:1000,end:999999},
	{start:500,end:999},
	{start:100,end:499},
	{start:10,end:99},
	{start:1,end:9}];

新增位置:
在这里插入图片描述

新增數據的視覺對映

在 optionMap 中新增數據的視覺對映

visualMap:{  //視覺對映(包括比例尺)
	left:'left',  //左右方向
	top:'bottom',  //豎直方向
	splitList:splitList1,
	color:['red','white'],  //定義兩個極值,中間顏色平均分配
	show:true
}

新增位置:
在这里插入图片描述

執行截圖

此時地圖上出現顏色和比例尺,且顏色隨 value 值從小到大而由白變紅。
在这里插入图片描述

具體步驟5:本地數據網頁完整程式碼

執行截圖與上圖一致

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<!-- 1. 匯入js相關的包 按照順序 echarts.js china.js jquery.js -->
		<script type="text/javascript" src="js/echarts.js"></script>
		<script type="text/javascript" src="js/china.js"></script>
		<script type="text/javascript" src="js/jquery.js"></script>
		<style>
			.title{
				font-size: 40px;
				font-family: "微軟雅黑";
				color: red;
			}
			.subtitle{
				font-size: 25px;
				color: orange;
			}
			.jiange{
				height: 30px;
				border: 0px solid black;
			}
			#chinamap{
				height: 600px;
				width: 800px;
				border: 1px solid black;
			}
		</style>
	</head>
	<body><center>
		<img src="1.png" alt="標題圖片" width="800px" height="343px">
		<div class="title"><b>全國疫情數據統計地圖</b></div>
		<div class="jiange"></div>
		<div class="subtitle">萬衆一心 堅決打贏疫情防控阻擊戰</div>
		<div class="jiange"></div>
		<div id="chinamap">
			<script>
				function initChinaMap() {
					var mydata = [{name: '北京',value: '253' },{name: '天津',value: '69' },
								  {name: '上海',value: '334' },{name: '重慶',value: '560' },
								  {name: '河北',value: '135' },{name: '河南',value: '1010' },
								  {name: '雲南',value: '124' },{name: '遼寧',value: '121' },
								  {name: '黑龍江',value: '190' },{name: '湖南',value: '661' },
								  {name: '安徽',value: '987' },{name: '山東',value: '307' },
								  {name: '新疆',value: '99' },{name: '江蘇',value: '631' },
								  {name: '浙江',value: '895' },{name: '江西',value: '548' },
								  {name: '湖北',value: '62031' },{name: '廣西',value: '150' },
								  {name: '甘肅',value: '57' },{name: '山西',value: '81' },
								  {name: '內蒙古',value: '42' },{name: '陝西',value: '165' },
								  {name: '吉林',value: '54' },{name: '福建',value: '205' },
								  {name: '貴州',value: '64' },{name: '廣東',value: '1332' },
								  {name: '青海',value: '17' },{name: '西藏',value: '1' },
								  {name: '四川',value: '301' },{name: '寧夏',value: '34' },
								  {name: '海南',value: '99' },{name: '臺灣',value: '99' },
								  {name: '香港',value: '21' },{name: '澳門',value: '10' }];
					//比例尺,放到visualMap中
					var splitList1 = [{start:1000,end:999999},
									  {start:500,end:999},
									  {start:100,end:499},
									  {start:10,end:99},
									  {start:1,end:9}];							
					<!-- 2. 建立圖紙 設定資訊 -->
					var optionMap = {
						backgroundColor: 'white',
						//提示工具(在滑鼠移動到指定元素後觸發)
						tooltip:{
							trigger:'item'
						},
						//設定屬性
						series: {
							name: '確診病例',
							type: 'map',
							mapType: 'china',  //地圖型別
							data: mydata,  //疫情數據{name, value}
							label:{
								normal:{
									show: true  //省份名稱
								},
								emphasis:{  //高亮樣式
									show: true,
									color: 'red'  //高亮時省份名的顏色
								}
							}
						},
						//左下角 導航圖例
						visualMap:{  //視覺對映(包括比例尺)
							left:'left',  //左右方向
							top:'bottom',  //豎直方向
							splitList:splitList1,
							color:['red','white'],  //定義兩個極值,中間顏色平均分配
							show:true
						}
					};
					<!-- 3. 建立工廠 初始化echarts -->
					// 初始化Echarts範例
					var myChart = echarts.init(document.getElementById('chinamap'));  // id = chinamap
					// 使用制定的設定項和數據顯示圖表
					myChart.setOption(optionMap);
				}
				initChinaMap();  //呼叫上面定義的函數
			</script>
		</div>
	</center></body>
</html>

具體步驟6:安裝jdk, Eclipse, Tomcat

1. jdk

jdk:這裏安裝的是jdk1.8.0_201
在这里插入图片描述
win10下預設安裝目錄的環境變數:

JAVA_HOME=C:\Program Files\Java\jdk1.8.0_201
PATH=%JAVA_HOME%\bin;%PATH%
CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

在这里插入图片描述

2. Eclipse

Eclipse:這裏使用的安裝包是 eclipse-inst-win64.exe
在这里插入图片描述
選擇第二個安裝
在这里插入图片描述
安裝時下載很慢,容易提示下載失敗,需要耐心多重新下載幾次
安裝後的圖示:
在这里插入图片描述

3. Tomcat

這裏使用的壓縮包版的 tomcat-8.0.42,解壓到D槽後即可使用
在这里插入图片描述

具體步驟7:新建一個Eclipse專案

1. 新建一個動態工程(Dynamic Web project)

開啓Eclipse後在左側列表空白處點選右鍵 → New → Project,進入選擇工程
在这里插入图片描述
在工程選擇裡搜尋 Dynamic Web project ,選擇後點擊 next
在这里插入图片描述
建立專案名稱,例如:Test_CSDN(不要出現中文),點選 Next,再點 Next

在这里插入图片描述
在这里插入图片描述
將 [Generate web.xml dployrment desritor] (生成 web.xml 部署描述符) 選中,點選 Finish
在这里插入图片描述
建立成功
在这里插入图片描述

2. 在Eclipse裡整合Tomcat

在下面 下麪的標籤欄中點選 Serves
或者從選單欄中的 Window → Show View 中直接或從 Other 中找到 Servers
點選 [No servers are available. Click this link to create a new server…]
在这里插入图片描述
選擇 Tomcat v8.0 Server,點選 Next
在这里插入图片描述
選擇安裝路徑,以能看到bin資料夾爲安裝路徑,點選 Next
在这里插入图片描述
遇到提示 [是否加入工程],什麼都不選,點選 Finish
在这里插入图片描述
回到主介面,雙擊 Severs 下面 下麪的 Tomcat 行,更改設定
在这里插入图片描述
更改第二項 Server Locations,改成第二個 Use Tomcat,Ctrl + S 儲存
在这里插入图片描述
更改第五項 Timeouts,將第一個開啓報錯時長改爲 150 秒,Ctrl + S 儲存
在这里插入图片描述
整合完成,在 Eclipse 內編寫的網頁可以通過 Tomcat 發佈,在本地從瀏覽器檢視
在这里插入图片描述
檢視方法:點右下方的綠色三角啓動鍵
在这里插入图片描述
稍等一會,直到下方日誌出現 Server startup in __ ms
在这里插入图片描述
在瀏覽器輸入地址 127.0.0.1:8081,會看到 Tomcat 的頁面,則設定成功
在这里插入图片描述

具體步驟8:將HBuilder編寫的程式碼放入Eclipse

將 HBuilder 左側列表的 js 資料夾複製到 Eclipse 專案中的 WebContent
在这里插入图片描述
在这里插入图片描述
將 HBuilder 左側列表的 yiqing.html 和圖片等附件檔案也複製到 Eclipse 專案中的 WebContent
在这里插入图片描述
在这里插入图片描述
複製粘貼後效果
在这里插入图片描述

使用 Tomcat 發佈做好的網頁

在伺服器關閉狀態下,右鍵單擊 Tomcat 8.0 Server,選擇 Add and Remove…
在这里插入图片描述
將 Test_CSDN 專案新增進來,點選 Finish
在这里插入图片描述
此時專案已經發布進來,可以點選在 Servers 左面的小三角檢視
在这里插入图片描述

存取測試

點選 start the Server
在这里插入图片描述
開啓成功後,瀏覽器存取 127.0.0.1:8081/Test_CSDN/yiqing.html
在这里插入图片描述

具體步驟9:建立servlet後臺程式碼

1. servlet 介紹

推薦在菜鳥教學(www.runoob.com)上學習 servlet 知識【點選進入】
(https://www.runoob.com/servlet/servlet-tutorial.html)

Servlet 爲建立基於 web 的應用程式提供了基於元件、獨立於平臺的方法
可以不受 CGI 程式的效能限制。
Servlet 有許可權存取所有的 Java API,包括存取企業級數據庫的 JDBC API。

2. 在 src 資料夾新建 Package

在專案列表中的 Test_CSDN → Java Resources → src 中新建一個 Package
在这里插入图片描述
一般開發 web 開頭爲 com,接公司名字,最後該 Package 的作用
例如:建立一個用於前臺接收(controller)的 Package
com.csdn.controller
在这里插入图片描述

新建 Package 後效果

在这里插入图片描述

3. 對新建好的 Package 新建一個 Servlet

在这里插入图片描述
例如:Servlet 的 Class name 爲 TestController
在这里插入图片描述

新建 Servlet 後效果

在这里插入图片描述

4. 修改 Build Path 解決報錯

右鍵點選 Package → Build Path → Configure Build Path…
在这里插入图片描述
選擇標籤中的 Libraries,點選 Add Library
在这里插入图片描述
選擇 Server Runtime,點選 Next
在这里插入图片描述
選擇 Tomcat 8.0,點選 Finish
在这里插入图片描述
Finish 返回後點擊 Apply,再點選 Apply and Close,完成設定
在这里插入图片描述

設定後效果(專案已經沒有報錯)

在这里插入图片描述

5. 修改專案的字元集亂碼

中文編碼:GBK、UTF-8,預設爲GBK,這裏使用UTF-8
右鍵點選專案,選擇 Properties
在这里插入图片描述
選擇列表中的 Resource,選中 Other,改爲UTF-8,點選 Apply,再點選 Apply and Close,修改完成
在这里插入图片描述

6. 修改 TestController.java 的字元集亂碼

在 doGet() 函數內先註釋掉自動生成的第一條語句,便於測試
在这里插入图片描述
新增兩條測試用的輸出語句

response.getWriter().append("Hello");
response.getWriter().append("你好");

新增位置
在这里插入图片描述
點選 Start the Server 後,瀏覽器存取 127.0.0.1:8081/Test_CSDN/TestController
中文部分會出現亂碼
在这里插入图片描述

修改字元集編碼方法

在 doGet() 函數中新增兩條語句

response.setHeader("content-type", "text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");

新增位置
在这里插入图片描述

修改後效果

儲存後,等待 Tomcat 伺服器載入後重新整理頁面,原來的中文亂碼部分恢復正常
在这里插入图片描述

具體步驟10:jquery實現ajax請求

1. ajax 介紹

推薦在菜鳥教學(www.runoob.com)上學習 ajax 知識【點選進入】
(https://www.runoob.com/ajax/ajax-tutorial.html)

AJAX = Asynchronous JavaScript and XML(非同步的 JavaScript 和 XML)。
AJAX 不是新的程式語言,而是一種使用現有標準的新方法。
AJAX 最大的優點是在不重新載入整個頁面的情況下,可以與伺服器交換數據並更新部分網頁內容。
AJAX 不需要任何瀏覽器外掛,但需要使用者允許JavaScript在瀏覽器上執行。
需要有以下基礎:
	HTML 和 CSS 基礎
	JavaScript 基礎
AJAX 應用:
· 運用XHTML+CSS來表達資訊;
· 運用JavaScript操作DOM(Document Object Model)來執行動態效果;
· 運用XML和XSLT操作資料;
· 運用XMLHttpRequest或新的Fetch API與網頁伺服器進行非同步資料交換;
注意:AJAX與Flash、Silverlight和Java Applet等RIA技術是有區分的。

2. 製作一個簡單的 ajax 測試 .html 頁面

在 WebContent 目錄下新建一個 TestAjax.html

先複製 Test_CSDN 專案的 WebContent 資料夾的所在地址
在这里插入图片描述
在 HBuilder 中開啓資料夾,並新建一個名爲 TestAjax.html 的檔案
在这里插入图片描述

編寫 html 測試程式碼

① 爲了區分測試效果與 TestController 的顯示結果,將 TestAjax.html 頁面顯示的值輸出爲紅色,id 爲 a

<style>
	#a{
		color: red;
	}
</style>

② ajax 的使用需要匯入 jquery.js

<script type = "text/javascript" src="js/jquery.js"></script>

③ 編寫 jquery 程式碼,功能爲請求一個網址(url),當存取成功(success)後,方法會返回一個接收值(result),函數將選擇 id 爲 a [ $("#aaa") ] 的 < div > 的程式碼中寫上 result 的內容 [ .text(result) ]
假設接收的網址(url)爲前面 TestController.java 的地址 TestController

<script type="text/javascript">
	$.ajax({
		url:"TestController",
		success: function(result){
			$("#aaa").text(result);
		}
	})
</script>

④ 最後在 < body > 中加上 id 爲 a 的顯示語句

<div id="a"></div>

新增位置
在这里插入图片描述

執行效果

使用瀏覽器存取地址 http://127.0.0.1:8081/Test_CSDN/TestAjax.html
顯示的內容爲從 TestController 中獲取的兩個輸出內容,並在 TestAjax.html 中設定爲紅色
在这里插入图片描述

具體步驟11:使用jsoup模擬瀏覽器獲得數據

1. jsoup 介紹

在菜鳥教學裡沒有找到完整的 jsoup 教學
推薦在開源社羣(www.open-open.com)學習【點選進入】
(https://www.open-open.com/jsoup/parsing-a-document.htm)

使用 jsoup 可以令 java 程式碼模擬瀏覽器進行存取
jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文字內容。
它提供了一套非常省力的API,可通過DOM,CSS以及類似於jQuery的操作方法來取出和操作數據。
Jsoup的主要功能
· 從一個URL,檔案或字串中解析HTML
· 使用DOM或CSS選擇器來查詢、取出數據
· 可操作HTML元素、屬性、文字
注意:jsoup是基於MIT協定發佈的,可放心使用於商業專案。

2. 製作一個簡單的 jsoup 測試 .java 程式碼

在 src 資料夾新建一個測試用的 Package

方法與步驟 9.1 相同,命名爲 com.csdn.test,用作 jsoup 的測試
在这里插入图片描述

在 Package 內新建一個類

右鍵點選 com.csdn.test → New → Class
在这里插入图片描述
命名爲 TestData,用於測試接收的數據
在这里插入图片描述
在这里插入图片描述

向 lib 中匯入 jar 包

也是放在了百度網盤裏分享,我設定的是永久有效,如果失效的話可以直接網上找同樣的檔名也能下載到。
鏈接: https://pan.baidu.com/s/1mMbrjhj2hbStHz9o9CsMow 提取碼: e49x

需要的 jar 包列表
在这里插入图片描述
將所有的 jar 包匯入到 WebContent → WEB-INF → lib 中
新增位置
在这里插入图片描述

新增在 eclipse 內測試的方法

在程式碼中加入一行即可

@Test

滑鼠放在程式碼所在位置上,選擇 JUnit5
在这里插入图片描述
完成後,滑鼠右鍵點選空白處,Run As 選項中會多出一個 JUnit Test
在这里插入图片描述
在 TestData 類中加入測試程式碼,測試後註釋掉

public void test1() {
	System.out.println("HELLO");
}

新增位置
在这里插入图片描述
儲存後,滑鼠右鍵 → Run As → JUnit Test 執行結果,測試成功
在这里插入图片描述

具體步驟12:編寫 TestData.java 的內容

1. 模擬瀏覽器存取

Connection con=Jsoup.connect()  // 輸入的地址
		.maxBodySize(0)  // 預設大小1024kb,設定爲0表示可以無限獲取
		.userAgent()  // 模擬瀏覽器的標頭檔案

此處的 Connection 爲 Jsoup 的 Connection,如果報錯時可以手動補全標頭檔案

import org.jsoup.Connection;
import org.jsoup.Jsoup;

其中,Jsoup.connect() 中的地址爲預定的 http://m.sinovision.net/newpneumonia.php

.connect("http://m.sinovision.net/newpneumonia.php")

.userAgent() 中的內容可以在存取頁面時在瀏覽器中複製
點選 F12 → Network → newpneumonia.php → Headers → 最底部 User-Agent
在这里插入图片描述
複製到 eclipse 後,如果覺得語句過長,在 " " 中按回車,軟體會自動將原字串分爲 " " + " " 的形式換行

.userAgent  // 模擬瀏覽器的標頭檔案
("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
	+ " Chrome/71.0.3573.0 Safari/537.36");

部分完整程式碼

定義一個存取,名爲 con

//模擬瀏覽器存取
Connection con=Jsoup.connect("http://m.sinovision.net/newpneumonia.php")  // 輸入地址的位址列
		.maxBodySize(0)  // 預設大小1024kb,設定爲0表示可以無限獲取
		.userAgent  // 模擬瀏覽器的標頭檔案
		("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
			+ " Chrome/71.0.3573.0 Safari/537.36");

新增位置

在这里插入图片描述

2. 設定一個響應

定義一個獲取的響應,名爲 rs

Connection.Response rs=null;

將響應 rs 定義爲 con 存取的響應,用到 execute() 方法,作用爲「執行」

rs=con.execute();

輸入後會提示 con.execute() 需要改進,選擇 Surrond with try/catch
在这里插入图片描述

改進後程式碼

Connection.Response rs=null;
try {
	rs=con.execute();
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

並且會自動新增一個頭檔案,用於處理 catch 中的 IOException

import java.io.IOException;

新增位置

在这里插入图片描述

3. 在 eclipse 中檢視響應是否收到

新增一行輸出收到的響應 rs 的 body 部分,測試後註釋掉即可

System.out.println(rs.body());  //列印獲得的頁面資訊

新增位置

在这里插入图片描述

執行截圖

儲存後,用具體步驟 9.2 同樣的方式執行
在这里插入图片描述

4. 階段性 TestData.Java 整體程式碼

執行截圖和上圖一致
將該階段(即僅獲得指定網址響應的內容並輸出至 eclipse)的整體程式碼 TestData.Java 列出

package com.csdn.test;

import java.io.IOException;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.junit.jupiter.api.Test;

public class TestData {
	// 使用jsoup模擬瀏覽器獲得數據
	@Test
	public void test1() {
		//System.out.println("HELLO");
		//模擬瀏覽器存取
		Connection con=Jsoup.connect("http://m.sinovision.net/newpneumonia.php")  // 輸入地址的位址列
				.maxBodySize(0)  // 預設大小1024kb,設定爲0表示可以無限獲取
				.userAgent  // 模擬瀏覽器的標頭檔案
				("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
						+ " Chrome/71.0.3573.0 Safari/537.36");
		Connection.Response rs=null;
		try {
			rs=con.execute();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(rs.body());  //列印獲得的頁面資訊
	}
}

具體步驟13:io流實現數據儲存本地

1. 新建一個用於儲存獲得資訊的資料夾

例如:在 D 盤中新建一個名爲 iotest 的資料夾
在这里插入图片描述

2. 新增一個將內容存入到原生的方法

例如:將方法函數命名爲 savetoDdisk,傳入的參數爲獲取到的 rs.body

public static void savetoDdisk(String rsbody) {}

新增位置
在这里插入图片描述
新建一個 Output 流,命名爲 fos

FileOutputStream fos=null;

之後會提示參照標頭檔案,參照後自動生成即可

import java.io.FileOutputStream
import java.io.PrintWriter

將 fos 定義爲輸出到 D:\iotest\a.txt
注意:當檔案路徑貼上到程式碼中後,原來的 「」 會變成 「\」

fos=new FileOutputStream("D:\\iotest\\a.txt",true);

新增後軟體會提示改進,選擇 Surrond with try/catch
在这里插入图片描述
將 catch 內容改爲 Exception即可,改進後程式碼

try {
	fos=new FileOutputStream("D:\\iotest\\a.txt",true);
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

在 try{} 內接着新增向 fos 指向檔案內寫入 rs.body 內容的語句

PrintWriter pw=new PrintWriter(fos,true);
pw.println(rsbody);
pw.close();

新增位置
在这里插入图片描述

3. 將 test1 方法中的輸出語句改爲呼叫語句

將原來的 System.out.println(rs.body()); 註釋掉,改爲呼叫 savetoDdisk 方法

savetoDdisk(rs.body());

新增位置
在这里插入图片描述

4. 階段性 TestData.Java 整體程式碼

將該階段(即僅獲得指定網址響應的內容並輸出至本地 .txt 檔案)的整體程式碼 TestData.Java 列出

package com.csdn.test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.junit.jupiter.api.Test;

public class TestData {
	// 使用jsoup模擬瀏覽器獲得數據
	@Test
	public void test1() {
		//System.out.println("HELLO");
		//模擬瀏覽器存取
		Connection con=Jsoup.connect("http://m.sinovision.net/newpneumonia.php")  // 輸入地址的位址列
				.maxBodySize(0)  // 預設大小1024kb,設定爲0表示可以無限獲取
				.userAgent  // 模擬瀏覽器的標頭檔案
				("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
						+ " Chrome/71.0.3573.0 Safari/537.36");
		Connection.Response rs=null;
		try {
			rs=con.execute();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println(rs.body());  //列印獲得的頁面資訊
		savetoDdisk(rs.body());
	}
	public static void savetoDdisk(String rsbody) {	
		//將rsbody儲存到D:\iotest
		FileOutputStream fos=null;
		try {
			fos=new FileOutputStream("D:\\iotest\\a.txt",true);
			PrintWriter pw=new PrintWriter(fos,true);
			pw.println(rsbody);
			pw.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

執行截圖

儲存後,選擇執行爲 JUnit Test,執行成功後不顯示內容
在这里插入图片描述
在 D:\iotest 中,會出現一個 a.txt 檔案,開啓後內容爲獲取到的 rs.body
在这里插入图片描述

具體步驟14:io流實現本地數據讀取到記憶體

1. 新增一個將本地數據讀取到記憶體的方法

例如:將方法函數命名爲 getLocalData,沒有傳入的參數

public void getLocalData() {}

新增位置
在这里插入图片描述

新建一個讀取本地檔案的物件,命名爲 read

InputStreamReader read=	
		new InputStreamReader(
				new FileInputStream("D:\\testyiqing\\a.txt"),"utf-8");

之後會提示參照標頭檔案,參照後自動生成即可

import java.io.FileInputStream;
import java.io.InputStreamReader;

新增後軟體會提示改進,選擇 Surrond with try/catch
在这里插入图片描述

留一個 try/catch,將 catch 內容改爲 Exception即可,改進後程式碼

try {
	InputStreamReader read=	
			new InputStreamReader(
					new FileInputStream("D:\\testyiqing\\a.txt"),"utf-8");
} catch(Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

在 try{} 內接着新增一個數據讀取(BufferedReader)物件,命名爲 br

BufferedReader br=new BufferedReader(read);

之後會提示參照標頭檔案,參照後自動生成即可

import java.io.BufferedReader;

再新增一個用於快取數據的物件(StringBuffer),命名爲 txt

StringBuffer txt=new StringBuffer();

定義一個字串,用於裝每一行讀取到的數據,命名爲 line

String line=null;

之後,使用 while 語句讀取檔案的每一行數據(line)儲存到快取物件 txt 中

while((line=br.readLine())!=null) {
	txt.append(line);
	txt.append("\n");
}

全部讀取後,關閉(close)讀取數據(BufferedReader br),並新增一條輸出在控制檯的語句

br.close();
System.out.println(txt.toString());

2. 程式測試

在 public void getLocalData() 的上一行加一條 @Test 語句,表示要對該方法進行 JUnit 測試

@Test
public void getLocalData(){}

原來的 public void test1() 上的 @Test 不用註釋掉,該函數同時呼叫了 savetoDdisk () 方法
表示 D:\iotest\a.txt 的內容依然爲 test1() 方法獲取,並由 savetoDdisk () 方法儲存的

3. 階段性 TestData.Java 整體程式碼

將該階段(即僅將本地 .txt 檔案內容讀取並輸出至控制檯)的整體程式碼 TestData.Java 列出

package com.csdn.test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.junit.jupiter.api.Test;

public class TestData {
	// 使用jsoup模擬瀏覽器獲得數據
	@Test
	public void test1() {
		//System.out.println("HELLO");
		//模擬瀏覽器存取
		Connection con=Jsoup.connect("http://m.sinovision.net/newpneumonia.php")  // 輸入地址的位址列
				.maxBodySize(0)  // 預設大小1024kb,設定爲0表示可以無限獲取
				.userAgent  // 模擬瀏覽器的標頭檔案
				("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
						+ " Chrome/71.0.3573.0 Safari/537.36");
		Connection.Response rs=null;
		try {
			rs=con.execute();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println(rs.body());  //列印獲得的頁面資訊
		savetoDdisk(rs.body());
	}
	public static void savetoDdisk(String rsbody) {	
		//將rsbody儲存到D:\iotest
		FileOutputStream fos=null;
		try {
			fos=new FileOutputStream("D:\\iotest\\a.txt",true);
			PrintWriter pw=new PrintWriter(fos,true);
			pw.println(rsbody);
			pw.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Test
	public void getLocalData() {
		//將D:\iotest\a.txt 數據獲得並放到記憶體中
		try {
			InputStreamReader read=	
			new InputStreamReader(
					new FileInputStream("D:\\iotest\\a.txt"),"utf-8");
			BufferedReader br=new BufferedReader(read);
			StringBuffer txt=new StringBuffer();
			String line=null;
			while((line=br.readLine())!=null) {
				txt.append(line);
				txt.append("\n");
			}
			br.close();
			System.out.println(txt.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}	
}

執行截圖

儲存後,選擇執行爲 JUnit Test,執行成功後操作檯顯示讀取到的 a.txt 的內容
在这里插入图片描述

具體步驟15:使用jsoup解析html頁面

1. 新增一個分析 html 頁面的方法

例如:將方法函數命名爲 analysisData,沒有傳入的參數

public void analysisData() {}

新增位置
在这里插入图片描述

2. 將 getLocalData() 的返回值型別改爲 String

將 getLocalData() 返回值改爲 String 型別

public static String getLocalData()

將 getLocalData() 變爲一種呼叫方法,即由 analysisData() 方法呼叫
所以註釋掉 getLocalData() 前面的測試語句 @Test
並在 try{} 中註釋掉控制檯輸出語句,改爲返回值

return txt.toString();

在方法結尾,也就是讀取失敗時,返回空

return null;

改動位置

在这里插入图片描述

3. 定義 analysisData() 方法

新增一個讀取本地檔案數據的字串,命名爲 resbody

String resbody=getLocalData();

把接收到的 html 程式碼用 Jsoup.parse() 方法轉換成 Document 文件,文件命名爲 doc

Document doc = Jsoup.parse(resbody);

之後會提示參照標頭檔案,參照後自動生成即可

import org.jsoup.nodes.Document;

觀察分析 a.txt 中的 html 程式碼

開啓 a.txt,觀察程式碼,可以發現本次需要的有 「省份」 和 「確診人數」
在 class=「todaydata」 → class=「prod」 → class=「area/confirm」 中
在这里插入图片描述
其中,todaydata 表示各個不同的數據分組,prod 表示省級地區
area 表示省級地區名稱,confirm 表示確診人數
則省份級別的地區名稱和確診人數簡單表示爲

<div class="todaydata">
	<div class="prod">
    	<span class="area">省級地區名稱</span>
        <span class="confirm">確診人數</span>
	</div>
</div>

在 a.txt 中 Ctrl + F 對 「todaydata」 進行查詢
可以發現中國省份資訊在有效的 < div class=「todaydata」 > 塊的第7項
在这里插入图片描述

根據觀察的分析編寫程式碼

按前面的分析步驟來編寫即可
獲取 doc 中(即 rs.body)所有的 class 爲 「todaydata」 的集合表(Elements 複數),命名爲 countrys

Elements countrys=doc.getElementsByClass("todaydata");

由前面查詢得到,中國數據資訊在 「todaydata」 塊的第7項(Element 單數)
獲取集合 countrys 的第7項(Element 單數),則 .get(6),命名爲 china

Element china=countrys.get(6);

取中國集合(Element 單數)中的所有 class 爲 「prod」 的省級數據資訊集合表(Element s 複數),命名爲 elements

Elements elements=china.getElementsByClass("prod");

遍歷輸出 elements 中的 class 爲 「area」 和 「confirm」 的地區名稱和確診人數的文字 [ .text() ]

for(Element en:elements) {
	System.out.println(en.getElementsByClass("area").text());
	System.out.println(en.getElementsByClass("confirm").text());
}

4. 程式測試

在 public void analysisData() 的上一行加一條 @Test 語句,表示要對該方法進行 JUnit 測試

@Test
public void analysisData()

前面的 getLocalData() 方法的 @Test 被註釋掉了,改爲返回值爲 String 型別
在 JUnit 測試 analysisData() 方法時有語句會呼叫 getLocalData() 方法

5. 階段性 TestData.Java 整體程式碼

將該階段(控制檯輸出中國省份名稱和確診人數)的整體程式碼 TestData.Java 列出

package com.csdn.test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.jupiter.api.Test;

public class TestData {
	// 使用jsoup模擬瀏覽器獲得數據
	@Test
	public void test1() {
		//System.out.println("HELLO");
		//模擬瀏覽器存取
		Connection con=Jsoup.connect("http://m.sinovision.net/newpneumonia.php")  // 輸入地址的位址列
				.maxBodySize(0)  // 預設大小1024kb,設定爲0表示可以無限獲取
				.userAgent  // 模擬瀏覽器的標頭檔案
				("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
						+ " Chrome/71.0.3573.0 Safari/537.36");
		Connection.Response rs=null;
		try {
			rs=con.execute();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println(rs.body());  //列印獲得的頁面資訊
		savetoDdisk(rs.body());
	}
	public static void savetoDdisk(String rsbody) {	
		//將rsbody儲存到D:\iotest
		FileOutputStream fos=null;
		try {
			fos=new FileOutputStream("D:\\iotest\\a.txt",true);
			PrintWriter pw=new PrintWriter(fos,true);
			pw.println(rsbody);
			pw.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//@Test
	public static String getLocalData() {
		//將D:\iotest\a.txt 數據獲得並放到記憶體中
		try {
			InputStreamReader read=	
			new InputStreamReader(
					new FileInputStream("D:\\iotest\\a.txt"),"utf-8");
			BufferedReader br=new BufferedReader(read);
			StringBuffer txt=new StringBuffer();
			String line=null;
			while((line=br.readLine())!=null) {
				txt.append(line);
				txt.append("\n");
			}
			br.close();
			//System.out.println(txt.toString());
			return txt.toString();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	@Test
	public void analysisData() {
		String resbody=getLocalData();
		Document doc = Jsoup.parse(resbody);
		Elements countrys=doc.getElementsByClass("todaydata");
		Element china=countrys.get(6);
		Elements elements=china.getElementsByClass("prod");
		for(Element en:elements) {
			System.out.println(en.getElementsByClass("area").text());
			System.out.println(en.getElementsByClass("confirm").text());
		}
	}
}

執行截圖

儲存後,選擇執行爲 JUnit Test,執行成功後控制檯輸出中國省份名稱和確診人數
在这里插入图片描述

具體步驟16:將獲取的數據發至前臺

1. 新建一個 servlet

在 com.csdn.controller 中新建一個 servlet,命名爲 GetJsonDataController
在这里插入图片描述
新增位置
在这里插入图片描述

2. 清空 doGet() 方法,並修改字元集編碼

與具體步驟 9.6 同樣方法,註釋掉自動生成的一條語句,並新增修改字元集編碼語句

response.setHeader("content-type", "text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");

新增位置
在这里插入图片描述

3. 移植 getLocalData() 方法,獲得本地資訊

將 com.csdn.test 中 TestData.java 的 public static String getLocalData() 方法整體複製貼上到 GetJsonDataController.java 的 GetJsonDataController 類中(即與類中其他方法同級)

public static String getLocalData() {
	//將D:\iotest\a.txt 數據獲得並放到記憶體中
	try {
		InputStreamReader read=	
		new InputStreamReader(
				new FileInputStream("D:\\iotest\\a.txt"),"utf-8");
		BufferedReader br=new BufferedReader(read);
		StringBuffer txt=new StringBuffer();
		String line=null;
		while((line=br.readLine())!=null) {
			txt.append(line);
			txt.append("\n");
		}
		br.close();
		//System.out.println(txt.toString());
		return txt.toString();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return null;
}

並在 doGet() 方法內部的前面呼叫該方法,即獲取本地資訊到字串,命名爲 rsbody

String resbody=getLocalData();

新增位置
在这里插入图片描述

4. 新建一個(地區名稱+確診人數)的類

需要新建一個類(class),裏面包含兩個成員變數:地區名稱(name)、確診人數(value)
在 src 中新建一個存放數據模型的 Package,命名爲 com.csdn.model
在这里插入图片描述
在 com.csdn.model 中新建一個省份數據類(class),命名爲 ProvinceData
在这里插入图片描述
新增後效果
在这里插入图片描述

5. 編寫 ProvinceData.java 程式碼

新增兩個成員變數,變數爲私有(private),省份名稱命名爲 name,確診人數命名爲 value

private String name;
private String value;

新增位置
在这里插入图片描述
給兩個成員變數新增 setter()、getter() 方法
除了手動編寫方法外,也可以用軟體自動生成
滑鼠在 ProvinceData 類內右鍵點選 → Source → Generate getters and setters
在这里插入图片描述
勾選 name 和 value 後,點選 OK 即可
在这里插入图片描述
新增後效果
在这里插入图片描述
會自動生成兩個成員變數的 setter()、getter() 方法

public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public String getValue() {
	return value;
}
public void setValue(String value) {
	this.value = value;
}

6. ProvinceData.java 完整程式碼

package com.csdn.model;

public class ProvinceData {
	private String name;
	private String value;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
}

7. 移植 analysisData() 方法,分析獲取的數據

將 com.csdn.test 中 TestData.java 的 public void analysisData() 方法整體複製貼上到 GetJsonDataController.java 的 GetJsonDataController 類中(即與類中其他方法同級)

public void analysisData() {
	String resbody=getLocalData();
	Document doc = Jsoup.parse(resbody);
	Elements countrys=doc.getElementsByClass("todaydata");
	Element china=countrys.get(6);
	Elements elements=china.getElementsByClass("prod");
	for(Element en:elements) {
		System.out.println(en.getElementsByClass("area").text());
		System.out.println(en.getElementsByClass("confirm").text());
	}
}

新增位置
在这里插入图片描述

8. 將省份和人數封裝到 ProvinceData 物件中

修改 analysisData() 方法
註釋掉原來 for(Element en:elements) {} 回圈中的兩條輸出語句

for(Element en:elements) {
	//System.out.println(en.getElementsByClass("area").text());
	//System.out.println(en.getElementsByClass("confirm").text());
}

在該回圈內新建一個 ProvinceData 類的物件,命名爲 p

ProvinceData p=	new ProvinceData();

之後會提示參照標頭檔案,參照後自動生成即可

import com.csdn.model.ProvinceData;

接着將原來的輸出語句改爲 setter() 方法賦值給類的物件 p,以字串形式 [ .toString() ]

p.setName(en.getElementsByClass("area").text().toString());
p.setValue(en.getElementsByClass("confirm").text().toString());

新增位置
在这里插入图片描述

9. 將多個 ProvinceData 物件封裝到 List 集合裡

在 analysisData() 方法中新建一個泛型爲 ProvinceData 物件的 List 集合,命名爲 list

List<ProvinceData> list=new ArrayList<ProvinceData>();

新增位置
在这里插入图片描述
之後會提示參照標頭檔案,參照後自動生成即可

import java.util.ArrayList;
import java.util.List;

在 for(Element en:elements) {} 回圈中新增將類物件 p 傳入集合 list 的語句

list.add(p);

新增位置
在这里插入图片描述

10. json 介紹

在菜鳥教學裡沒有找到完整的 json 教學
推薦在開源社羣(www.open-open.com)學習【點選進入】
(https://www.runoob.com/json/json-tutorial.html)

JSON 指的是 JavaScript 物件表示法(JavaScript Object Notation)
JSON 是輕量級的文字數據交換格式
JSON 獨立於語言:JSON 使用 Javascript語法來描述數據物件,但是 JSON 仍然獨立於語言和平臺。
JSON 解析器和 JSON 庫支援許多不同的程式語言。 
目前非常多的動態(PHP,JSP,.NET)程式語言都支援JSON。
JSON 具有自我描述性,更易理解
JSON 範例
{
    "sites": [
    { "name":"菜鳥教學" , "url":"www.runoob.com" }, 
    { "name":"google" , "url":"www.google.com" }, 
    { "name":"微博" , "url":"www.weibo.com" }
    ]
}
這個 sites 物件是包含 3 個站點記錄(物件)的陣列。

11. 將 analysisData() 的返回值改爲 json 字串

這裏使用 fastion 的 jar 包,快速生成一個 json 字串
在 analysisData() 方法內部的結尾,新增一個將列表物件 list 轉化爲 json 字串的語句
字串命名爲 jsonstr

String jsonstr=JSON.toJSONString(list,true);

之後會提示參照標頭檔案,參照後自動生成即可

import com.alibaba.fastjson.JSON;

將 analysisData() 的返回值改爲 json 字串,型別爲 String

public String analysisData() {}

並且在 analysisData() 方法的結尾新增返回字串 jsonstr 語句

return jsonstr;

修改位置
在这里插入图片描述

12. 在 doGet() 方法中呼叫 analysisData() 方法

將字串返回給前臺的語句在具體步驟 9.6 有過簡單測試

response.getWriter().append(內容);

解析原生的 a.txt 中的 html 程式碼,並且獲得需要的 json 字串,返回給前臺
在 doGet() 方法內部的結尾新增將 analysisData() 方法的返回值 jsonstr 返回給前臺

String jsonstr=analysisData() ;
response.getWriter().append(jsonstr);

新增位置
在这里插入图片描述

13. GetJsonDataController.java 完整程式碼

此時 GetJsonDataController.java 的所有內容已經編寫完成

package com.csdn.controller;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSON;
import com.csdn.model.ProvinceData;


/**
 * Servlet implementation class GetJsonDataController
 */
@WebServlet("/GetJsonDataController")
public class GetJsonDataController extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GetJsonDataController() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		//解決亂碼
		response.setHeader("content-type", "text/html; charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		//獲得本地資訊
		String resbody=getLocalData();
		// 解析原生的 html,分析獲得需要的json字串,返回給前臺
		String jsonstr=analysisData() ;
		response.getWriter().append(jsonstr);
	}
	
	public String analysisData() {
		String resbody=getLocalData();
		Document doc = Jsoup.parse(resbody);
		Elements countrys=doc.getElementsByClass("todaydata");
		Element china=countrys.get(6);
		Elements elements=china.getElementsByClass("prod");
		List<ProvinceData> list=new ArrayList<ProvinceData>();
		for(Element en:elements) {
			//System.out.println(en.getElementsByClass("area").text());
			//System.out.println(en.getElementsByClass("confirm").text());
			ProvinceData p=	new ProvinceData();
			p.setName(en.getElementsByClass("area").text().toString());
			p.setValue(en.getElementsByClass("confirm").text().toString());
			list.add(p);
		}
		String jsonstr=JSON.toJSONString(list,true);
		return jsonstr;
	}
	
	public static String getLocalData() {
		//將D:\iotest\a.txt 數據獲得並放到記憶體中
		try {
			InputStreamReader read=	
			new InputStreamReader(
					new FileInputStream("D:\\iotest\\a.txt"),"utf-8");
			BufferedReader br=new BufferedReader(read);
			StringBuffer txt=new StringBuffer();
			String line=null;
			while((line=br.readLine())!=null) {
				txt.append(line);
				txt.append("\n");
			}
			br.close();
			//System.out.println(txt.toString());
			return txt.toString();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
}

具體步驟17:修改html頁面的數據

1. 用 HBuilder 開啓 yiqing.html

開啓 Test_CSDN\WebContent\yiqing.html 進行修改
在这里插入图片描述

2. 註釋掉原有的內部定義的疫情數據

將原來的 mydata 數據註釋掉,準備替換後臺數據
註釋位置
在这里插入图片描述

3. 在 initChinaMap() 函數前新增 ajax 請求

關於 ajax 請求的程式碼在具體步驟 10.2 有過簡單測試

$.ajax({
	url:"TestController",
	success: function(result){
		$("#aaa").text(result);
	}
})

將 url 地址改爲前面編寫的後臺程式碼 「GetJsonDataController」
接收數據型別(dataType)設定爲 ‘json’ 型別
將原來的輸出語句改爲把接收的內容(result)賦值給一個變數(var),命名爲 dataresult
即把 GetJsonDataController.java 中的 jsonstr 賦值給了 yiqing.html 中的 dataresult

$.ajax({
	url:"GetJsonDataController",
	dataType:'json',
	success: function(result){
		// $("#aaa").text(result);
		dataresult=result
	}
})

新增位置
在这里插入图片描述

4. 修改疫情數據 mydata

將原來本地定義的 mydata 註釋掉後,改爲賦值爲 ajax 請求到的 dataresult

var mydata = dataresult;

新增位置
在这里插入图片描述

5. 更改 initChinaMap() 函數執行的位置

將原來的 initChinaMap(); 執行語句註釋掉

// initChinaMap();  //呼叫上面定義的函數

改爲在 ajax 請求中的 success{} 內部最後執行

$.ajax({
	url:"GetJsonDataController",
	dataType:'json',
	success: function(result){
		// $("#aaa").text(result);
		dataresult=result;
		initChinaMap();
	}
})

修改位置
在这里插入图片描述

具體步驟18: 後臺數據網頁完整程式碼

具體步驟 17 修改後的 Test_CSDN\WebContent\yiqing.html 的完整程式碼

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<!-- 1. 匯入js相關的包 按照順序 echarts.js china.js jquery.js -->
		<script type="text/javascript" src="js/echarts.js"></script>
		<script type="text/javascript" src="js/china.js"></script>
		<script type="text/javascript" src="js/jquery.js"></script>
		<style>
			.title{
				font-size: 40px;
				font-family: "微軟雅黑";
				color: red;
			}
			.subtitle{
				font-size: 25px;
				color: orange;
			}
			.jiange{
				height: 30px;
				border: 0px solid black;
			}
			#chinamap{
				height: 600px;
				width: 800px;
				border: 1px solid black;
			}
		</style>
	</head>
	<body><center>
		<img src="1.png" alt="標題圖片" width="800px" height="343px">
		<div class="title"><b>全國疫情數據統計地圖</b></div>
		<div class="jiange"></div>
		<div class="subtitle">萬衆一心 堅決打贏疫情防控阻擊戰</div>
		<div class="jiange"></div>
		<div id="chinamap">
			<script>
				$.ajax({
					url:"GetJsonDataController",
					dataType:'json',
					success: function(result){
						// $("#aaa").text(result);
						dataresult=result;
						initChinaMap();
					}
				})
				function initChinaMap() {
					/*var mydata = [{name: '北京',value: '253' },{name: '天津',value: '69' },
								  {name: '上海',value: '334' },{name: '重慶',value: '560' },
								  {name: '河北',value: '135' },{name: '河南',value: '1010' },
								  {name: '雲南',value: '124' },{name: '遼寧',value: '121' },
								  {name: '黑龍江',value: '190' },{name: '湖南',value: '661' },
								  {name: '安徽',value: '987' },{name: '山東',value: '307' },
								  {name: '新疆',value: '99' },{name: '江蘇',value: '631' },
								  {name: '浙江',value: '895' },{name: '江西',value: '548' },
								  {name: '湖北',value: '62031' },{name: '廣西',value: '150' },
								  {name: '甘肅',value: '57' },{name: '山西',value: '81' },
								  {name: '內蒙古',value: '42' },{name: '陝西',value: '165' },
								  {name: '吉林',value: '54' },{name: '福建',value: '205' },
								  {name: '貴州',value: '64' },{name: '廣東',value: '1332' },
								  {name: '青海',value: '17' },{name: '西藏',value: '1' },
								  {name: '四川',value: '301' },{name: '寧夏',value: '34' },
								  {name: '海南',value: '99' },{name: '臺灣',value: '99' },
								  {name: '香港',value: '21' },{name: '澳門',value: '10' }];*/ 
					var mydata = dataresult;
					//比例尺,放到visualMap中
					var splitList1 = [{start:1000,end:999999},
									  {start:500,end:999},
									  {start:100,end:499},
									  {start:10,end:99},
									  {start:1,end:9}];							
					<!-- 2. 建立圖紙 設定資訊 -->
					var optionMap = {
						backgroundColor: 'white',
						//提示工具(在滑鼠移動到指定元素後觸發)
						tooltip:{
							trigger:'item'
						},
						//設定屬性
						series: {
							name: '確診病例',
							type: 'map',
							mapType: 'china',  //地圖型別
							data: mydata,  //疫情數據{name, value}
							label:{
								normal:{
									show: true  //省份名稱
								},
								emphasis:{  //高亮樣式
									show: true,
									color: 'red'  //高亮時省份名的顏色
								}
							}
						},
						//左下角 導航圖例
						visualMap:{  //視覺對映(包括比例尺)
							left:'left',  //左右方向
							top:'bottom',  //豎直方向
							splitList:splitList1,
							color:['red','white'],  //定義兩個極值,中間顏色平均分配
							show:true
						}
					};
					<!-- 3. 建立工廠 初始化echarts -->
					// 初始化Echarts範例
					var myChart = echarts.init(document.getElementById('chinamap'));  // id = chinamap
					// 使用制定的設定項和數據顯示圖表
					myChart.setOption(optionMap);
				}
				// initChinaMap();  //呼叫上面定義的函數
			</script>
		</div>
	</center></body>
</html>

具體步驟19:最終測試執行

返回 eclipse,選中 Test_CSDN 專案,點選 Start the server,開啓伺服器
在这里插入图片描述
開啓成功
在这里插入图片描述
開啓瀏覽器,輸入地址 http://127.0.0.1:8081/Test_CSDN/yiqing.html
在这里插入图片描述
可以發現疫情數據疫情發生變化
以北京爲例,原來本地數據中北京的確診人數爲 253,先現在網頁顯示爲 935
在这里插入图片描述
且該數據 935 與 D:\iotest\a.txt 中的數據相同,說明測試成功
在这里插入图片描述

專案完整程式碼(壓縮包)

還是放在了百度網盤裏分享,我設定的是永久有效,如果失效的話可以按照文章的整體程式碼複製,或者留言。

鏈接: https://pan.baidu.com/s/1wS-5er4QOGaeib0oJnw2bg 提取碼: 3dhp

專案完成體會

在實際的專案面前,學校課本上的知識僅能提供基礎的簡單語句的理解,很多的知識幾乎都是在實踐中現學的,有成功的案例、可回放的筆記和錄像、隨時能搜尋的知識點,是自學的最好幫手。