目錄
一、本篇簡介
二、URL類
三、基于URL類的網頁下載
1、發送按鈕
2、接收資料的多執行緒
四、URL網頁下載客戶端
五、撰寫web瀏覽器
1、WebEngine類
2、WebView類
3、WebHistory類
六、簡易瀏覽器關鍵步驟代碼
1、首頁加載按鈕
2、重繪按鈕
3、跳轉按鈕
4、前進/后退按鈕
5、狀態監聽器
6、效果演示
一、本篇簡介
本篇記錄Java之HTTP網路編程,定位于網頁瀏覽器程式設計,與上篇TCP/SSL網頁下載有所不同,接下來將實作通過URL進行網頁的下載以及編程簡易瀏覽器訪問網站,網頁下載程式簡潔清晰,可以訪問網站,獲取界面的原始碼;簡易瀏覽器擁有基礎功能,包括訪問網頁,重繪,下載,聽音樂……還有很多可以嘗試的功能,模仿常用的瀏覽器!
基礎知識的學習主要在上一篇,可查看Java之HTTP網路編程(上篇:TCP/SSL網頁下載),
二、URL類
上一篇通過TCP/SSL直接發送http請求的程式,對于復雜的地址,例如指向具體頁面的地址,無法完成網頁下載任務,因此這里使用Java中提供的URL類,解決網頁訪問的問題,
URL(Uniform Resource Locator):統一資源定位符,用于表示資源地址,資源如網頁或者FTP地址等,URL的格式為protocol://資源地址,protocol可以是HTTP、HTTPS、FTP 和 File,資源地址中可以帶有埠號及查詢引數,例如https://www.baidu.com
在java中,URL類用來處理有關URL的內容,并且其封裝有一個InputStream回傳型別的openStream()方法,程式就可以讀取這個位元組輸入流來獲得對應內容,
URL url = new URL(address);
//獲得url的位元組流輸入
InputStream in = url.openStream();
//裝飾成字符輸入流
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
相比于發送HTTP請求頭的方式,使用URL獲取網頁內容顯得更加簡單,回傳結果也存在不同之處,接下來介紹具體實作,
三、基于URL類的網頁下載
界面如圖:

這里的界面實作不再貼出代碼,與之前類似,只需稍作修改,下面給出關鍵的代碼,
1、發送按鈕
在發送按鈕事件中,使用URL類對輸入的URL地址進行決議,指定一“http”開頭的才是有效的網址,然后使用InputStream包含的方法接收網頁內容,
//網頁請求按鈕事件
btnSend.setOnAction(event -> {
taDisplay.clear();
String domainName=tfSend.getText().trim();
if (!domainName.substring(0,4).equals("http"))
taDisplay.appendText("URL地址輸入不合規則!");
try {
URL url = new URL(domainName);
System.out.println("連接"+domainName+"成功!\n");
InputStream in=url.openStream();
br=new BufferedReader(new InputStreamReader(in,"utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
});
2、接收資料的多執行緒
可以發現,一按發送按鈕,立即觸發與網站的通信,對方服務器會回傳網頁內容,這里就包括了多次的資訊的發送和接收,所以,我們的客戶端需要實作接收網頁資料的多執行緒,避免阻塞完整內容的接收,
readThread = new Thread(()->{
String receiveMsg=null;//從服務器接收一串字符
try {
while ((receiveMsg=br.readLine())!=null){
String msgTemp = receiveMsg;
Platform.runLater(()->{
taDisplay.appendText(msgTemp+"\n");
});
}
}catch (IOException e){
e.printStackTrace();
}
Platform.runLater(()->{
taDisplay.appendText("對話已關閉!\n");
});
});
readThread.start();
開啟一個接收服務器資訊的執行緒,專門處理接收資料,這部分添加到發送按鈕中,觸發按鈕事件時候便啟動執行緒,達到完整接收資訊的目的,
四、URL網頁下載客戶端

這樣就實作了網頁的下載,相當于一個小工具,獲取網頁的HTML源代碼!
五、撰寫web瀏覽器
前面的所有程式都只是實作了網頁檔案的下載,沒有經過渲染得到瀏覽網頁的效果,下面就實作網頁顯示功能,首先認識一下JavaFX的WebEngine、WebView、WebHistory類相關內容,然后實作自己簡單的瀏覽器,
1、WebEngine類
WebEngine類提供了基本的web頁面功能,盡管它并不與用戶直接互動,但它也支持用戶互動,如導航鏈接和提交HTML表單,WebEngine類一次處理一個web頁面,支持加載HTML內容和訪問DOM物件等基本功能,也支持執行JavaScript指令,
創建WebEngine物件的兩個構造方法:空構造和帶一個URL引數的構造,
如果你使用空構造方法來實體化它,那么URL可以通過WebEngine物件的load()方法來傳入,WebEngine物件實體的getLocation()方法會回傳當前加載頁面的URL地址,
2、WebView類
WebView類是Node類的一個擴展,它封裝了WebEngine物件,將HTML內容加入程式的scene中,并且提供各種屬性和方法來應用特效和變換,WebView物件的getEngine()方法回傳一個與之關聯的web engine,例如可以這樣使用:
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.load("https://www.baidu.com");
當load另一個URL,webView就自動加載另外一個頁面,
3、WebHistory類
WebHistory類可獲取已訪問的頁面串列,它表示與WebEngine物件關聯的一個會話歷史記錄,WebEngine.getHistory()方法可以獲取某特定webEngine物件的WebHistory實體,
WebHistory history = webEngine.getHistory();
該歷史記錄基本上是一種特殊型別的串列,類似普通List,該串列也是下標從0開始,每一個條目表示一個已訪問過的頁面并且提供對該頁面相關資訊的訪問,該串列可通過getEntries()方法獲得,
該物件的getCurrentIndex()方法回傳值表示當前訪問頁面在串列中的索引位置,該物件的go(int index)方法表示頁面的跳轉,例如history.go(-1)就是回傳上一個訪問的頁面,history.go(1)表示前進到下一個訪問過的頁面,這兩個方法使用要注意邊界條件判斷,否則會拋出例外,例如已經沒有可回退的頁面記錄,再執行回退方法就拋出例外,

瀏覽器頁面組件如上圖,接下來給出具體關鍵步驟的實作,
六、簡易瀏覽器關鍵步驟代碼
1、首頁加載按鈕
首先,宣告成員變數以及創建Web物件:
private Button fresh=new Button("重繪");
private Button forward=new Button("前進");
private Button backward=new Button("后退");
private Button mainIndex=new Button("首頁");
private Button enter=new Button("跳轉");
private TextField urlSend=new TextField();
WebView webView=new WebView();
WebEngine webEngine=webView.getEngine();
JavaFx表單可以重用上一篇的內容,這里只需要將webView組件添加到中央,
borderPane.setCenter(webView);
需要注意的是,實作按鈕的功能,必須符合程式執行邏輯,以免誤操作出現例外,比如“前進”、“后退”按鈕使用中,需要獲取網頁加載串列的邊界長度,才能正常讀取歷史訪問記錄,
因此,在適當的時候禁用相關按鈕可以保證程式正常運行,
forward.setDisable(true);
backward.setDisable(true);
fresh.setDisable(true);
一些準備作業完成之后,開始撰寫按鈕事件,相對簡單,
//首頁
mainIndex.setOnAction(event -> {
webEngine.load("https://www.baidu.com");
fresh.setDisable(false);
});
2、重繪按鈕
重繪方法比較粗暴,獲取當前頁面的URL,重新加載該頁面,
//重繪按鈕
fresh.setOnAction(event ->{
WebHistory history=webEngine.getHistory();
// 獲取當前頁面的URL,重新加載該頁面
webEngine.load(history.getEntries().get(history.getCurrentIndex()).getUrl());
});
3、跳轉按鈕
獲取輸入區的URL地址,交給webEngine加載網頁,
//跳轉按鈕
enter.setOnAction(event -> {
String url=urlSend.getText();
if (url!=null){
webEngine.load(url);
backward.setDisable(false);
fresh.setDisable(false);
}
});
4、前進/后退按鈕
“前進”和“后退”按鈕能夠根據實際情況自動禁用和啟用,所以進行歷史記錄條目長度的判斷,
//前進
forward.setOnAction(event -> {
WebHistory history=webEngine.getHistory();
//判斷已訪問頁面數與當前頁面下標大小,再執行前進操作
if (history.getCurrentIndex()+1<history.getEntries().size()){
history.go(1);
backward.setDisable(false);
}
else {
forward.setDisable(true);
}
});
//后退
backward.setOnAction(event -> {
WebHistory history=webEngine.getHistory();
if (history.getCurrentIndex()-1>=0){
history.go(-1);
forward.setDisable(false);
}
else {
backward.setDisable(true);
}
});
5、狀態監聽器
使用webEngine的狀態監聽器,監聽頁面的載入狀態,只要頁面有載入動作,就會觸發其中的代碼,在這個監聽器中設定前進后退按鈕的可用性,
webEngine.getLoadWorker().stateProperty().addListener((observable,oldValue,newValue) -> {
forward.setDisable(false);
backward.setDisable(false);
});
6、效果演示
完整演示視頻
web瀏覽器


如果覺得不錯歡迎“一鍵三連”哦,點贊收藏關注,有問題直接評論,交流學習!
Java之HTTP網路編程:
- 上篇:TCP/SSL網頁下載【https://blog.csdn.net/Charzous/article/details/111470556】
- 下篇:網頁瀏覽器程式設計【https://blog.csdn.net/Charzous/article/details/112254723】
我的CSDN博客:https://blog.csdn.net/Charzous/article/details/112254723
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/245718.html
標籤:其他
