目录
一、本篇简介
二、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网页下载)。
上一篇通过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类对输入的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();
}
});
可以发现,一按发送按钮,立即触发与网站的通信,对方服务器会返回网页内容,这里就包括了多次的信息的发送和接收。所以,我们的客户端需要实现接收网页数据的多线程,避免阻塞完整内容的接收。
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();
开启一个接收服务器信息的线程,专门处理接收数据,这部分添加到发送按钮中,触发按钮事件时候便启动线程,达到完整接收信息的目的。
这样就实现了网页的下载,相当于一个小工具,获取网页的HTML源代码!
前面的所有程序都只是实现了网页文件的下载,没有经过渲染得到浏览网页的效果,下面就实现网页显示功能,首先认识一下JavaFX的WebEngine、WebView、WebHistory类相关内容,然后实现自己简单的浏览器。
WebEngine类提供了基本的web页面功能。尽管它并不与用户直接交互,但它也支持用户交互,如导航链接和提交HTML表单。WebEngine类一次处理一个web页面,支持加载HTML内容和访问DOM对象等基本功能,也支持执行JavaScript指令。
创建WebEngine对象的两个构造方法:空构造和带一个URL参数的构造。
如果你使用空构造方法来实例化它,那么URL可以通过WebEngine对象的load()方法来传入。WebEngine对象实例的getLocation()方法会返回当前加载页面的URL地址。
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就自动加载另外一个页面。
WebHistory类可获取已访问的页面列表,它表示与WebEngine对象关联的一个会话历史记录。WebEngine.getHistory()方法可以获取某特定webEngine对象的WebHistory实例。
WebHistory history = webEngine.getHistory();
该历史记录基本上是一种特殊类型的列表。类似普通List,该列表也是下标从0开始,每一个条目表示一个已访问过的页面并且提供对该页面相关信息的访问。该列表可通过getEntries()方法获得。
该对象的getCurrentIndex()方法返回值表示当前访问页面在列表中的索引位置。该对象的go(int index)方法表示页面的跳转,例如history.go(-1)就是返回上一个访问的页面,history.go(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);
});
刷新方法比较粗暴,获取当前页面的URL,重新加载该页面。
//刷新按钮
fresh.setOnAction(event ->{
WebHistory history=webEngine.getHistory();
// 获取当前页面的URL,重新加载该页面
webEngine.load(history.getEntries().get(history.getCurrentIndex()).getUrl());
});
获取输入区的URL地址,交给webEngine加载网页。
//跳转按钮
enter.setOnAction(event -> {
String url=urlSend.getText();
if (url!=null){
webEngine.load(url);
backward.setDisable(false);
fresh.setDisable(false);
}
});
“前进”和“后退”按钮能够根据实际情况自动禁用和启用。所以进行历史记录条目长度的判断。
//前进
forward.setOnAction(event -> {
WebHistory history=webEngine.getHistory();
//判断已访问页面数与当前页面下标大小,再执行前进操作
if (history.getCurrentIndex()+1 {
WebHistory history=webEngine.getHistory();
if (history.getCurrentIndex()-1>=0){
history.go(-1);
forward.setDisable(false);
}
else {
backward.setDisable(true);
}
});
使用webEngine的状态监听器,监听页面的载入状态,只要页面有载入动作,就会触发其中的代码。在这个监听器中设置前进后退按钮的可用性。
webEngine.getLoadWorker().stateProperty().addListener((observable,oldValue,newValue) -> {
forward.setDisable(false);
backward.setDisable(false);
});
完整演示视频
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