当前位置: 首页 > news >正文

零基础学Java——第八章:Java网络编程(下)

第八章:Java网络编程(下)

在上一部分中,我们学习了Java网络编程的基础知识,包括网络通信的基本概念、Socket编程和URL处理。在这一部分中,我们将继续深入学习更多高级的网络编程内容,包括HTTP客户端、网络爬虫入门和邮件发送等。

1. HTTP客户端

HTTP(超文本传输协议)是互联网上最常用的协议之一,用于在Web浏览器和网站服务器之间传输数据。Java提供了多种方式来实现HTTP客户端。

1.1 使用HttpURLConnection

HttpURLConnectionURLConnection的子类,专门用于处理HTTP连接。

想象一下:如果说普通的URLConnection就像是一个通用的信使,可以传递各种类型的消息,那么HttpURLConnection就像是一个专门负责HTTP协议的信使,它懂得HTTP的所有规则和礼仪。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;public class HttpURLConnectionDemo {public static void main(String[] args) {try {// 创建URL对象URL url = new URL("https://www.baidu.com");// 打开连接并转换为HttpURLConnectionHttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置请求方法(默认为GET)connection.setRequestMethod("GET");// 设置连接超时时间(毫秒)connection.setConnectTimeout(5000);// 设置读取超时时间(毫秒)connection.setReadTimeout(5000);// 设置请求头connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");// 获取响应码int responseCode = connection.getResponseCode();System.out.println("响应码: " + responseCode);// 如果响应成功(状态码为200)if (responseCode == HttpURLConnection.HTTP_OK) {// 读取响应内容BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));String line;StringBuilder response = new StringBuilder();while ((line = reader.readLine()) != null) {response.append(line);response.append("\n");}reader.close();// 打印前100个字符的响应内容System.out.println("响应内容(前100个字符): " + response.substring(0, Math.min(100, response.length())));} else {System.out.println("HTTP请求失败");}// 断开连接connection.disconnect();} catch (IOException e) {e.printStackTrace();}}
}

1.2 发送POST请求

有时我们需要向服务器发送数据,这通常通过POST请求完成。

想象一下:如果GET请求就像是在信箱上贴一张便条询问信息,那么POST请求就像是寄出一个包裹,里面装满了你想发送的数据。

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;public class HttpPostDemo {public static void main(String[] args) {try {// 创建URL对象URL url = new URL("http://httpbin.org/post");// 打开连接HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置为POST请求connection.setRequestMethod("POST");// 启用输入输出流connection.setDoOutput(true);connection.setDoInput(true);// 设置请求头connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");// 准备POST参数String name = URLEncoder.encode("张三", "UTF-8");String age = URLEncoder.encode("25", "UTF-8");String postData = "name=" + name + "&age=" + age;// 发送POST数据try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {wr.writeBytes(postData);wr.flush();}// 获取响应码int responseCode = connection.getResponseCode();System.out.println("响应码: " + responseCode);// 读取响应内容BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));String line;StringBuilder response = new StringBuilder();while ((line = reader.readLine()) != null) {response.append(line);response.append("\n");}reader.close();// 打印响应内容System.out.println("响应内容: " + response.toString());// 断开连接connection.disconnect();} catch (IOException e) {e.printStackTrace();}}
}

1.3 使用HttpClient(Java 11+)

Java 11引入了新的HTTP客户端API,它提供了更现代、更易用的HTTP客户端实现。

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;public class HttpClientDemo {public static void main(String[] args) {try {// 创建HttpClientHttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2)  // 使用HTTP/2.connectTimeout(Duration.ofSeconds(5))  // 设置连接超时.build();// 创建HttpRequestHttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://www.baidu.com")).header("User-Agent", "Java HttpClient").GET()  // 设置为GET请求.build();// 发送请求并获取响应HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());// 打印响应信息System.out.println("响应码: " + response.statusCode());System.out.println("响应头: " + response.headers());System.out.println("响应内容(前100个字符): " + response.body().substring(0, Math.min(100, response.body().length())));} catch (IOException | InterruptedException e) {e.printStackTrace();}}
}

2. 网络爬虫入门

网络爬虫是一种自动获取网页内容的程序。在Java中,我们可以使用前面学习的HTTP客户端和一些HTML解析库来实现简单的网络爬虫。

2.1 HTML解析

为了解析HTML内容,我们可以使用第三方库,如Jsoup。Jsoup是一个Java的HTML解析器,可以直接解析URL或HTML文本。

想象一下:如果说HTML页面是一本书,那么Jsoup就像是一个能够理解这本书结构的助手,它可以帮你找到书中的章节、段落和重要内容。

首先,我们需要添加Jsoup依赖。如果使用Maven,可以在pom.xml中添加:

<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.14.3</version>
</dependency>

如果不使用Maven,可以从Jsoup官网下载JAR文件并添加到项目的类路径中。

下面是一个使用Jsoup解析网页的例子:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;import java.io.IOException;public class JsoupDemo {public static void main(String[] args) {try {// 从URL加载文档Document doc = Jsoup.connect("https://news.baidu.com/").userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36").timeout(5000).get();// 获取页面标题String title = doc.title();System.out.println("页面标题: " + title);// 使用CSS选择器选择元素Elements newsLinks = doc.select(".hotnews a");System.out.println("\n热门新闻链接:");for (Element link : newsLinks) {// 获取链接文本和URLString linkText = link.text();String linkHref = link.attr("href");System.out.println(linkText + " - " + linkHref);}} catch (IOException e) {e.printStackTrace();}}
}

2.2 实现简单的网络爬虫

下面是一个更完整的网络爬虫示例,它可以爬取一个网站的所有链接:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;import java.io.IOException;
import java.util.HashSet;
import java.util.Set;public class SimpleCrawler {// 已访问的URL集合private Set<String> visitedUrls = new HashSet<>();// 待访问的URL集合private Set<String> urlsToVisit = new HashSet<>();// 限制爬取的URL数量private int maxUrlsToVisit = 100;// 基础URL,用于解析相对URLprivate String baseUrl;public SimpleCrawler(String startUrl, int maxUrls) {this.urlsToVisit.add(startUrl);this.maxUrlsToVisit = maxUrls;this.baseUrl = extractBaseUrl(startUrl);}private String extractBaseUrl(String url) {// 简单地提取基础URL(域名部分)if (url.startsWith("http://")) {url = url.substring(7);} else if (url.startsWith("https://")) {url = url.substring(8);}int slashIndex = url.indexOf('/');if (slashIndex != -1) {url = url.substring(0, slashIndex);}return url;}public void crawl() {while (!urlsToVisit.isEmpty() && visitedUrls.size() < maxUrlsToVisit) {// 获取下一个要访问的URLString currentUrl = urlsToVisit.iterator().next();urlsToVisit.remove(currentUrl);// 如果已经访问过,则跳过if (visitedUrls.contains(currentUrl)) {continue;}try {// 访问URL并解析页面System.out.println("正在爬取: " + currentUrl);Document doc = Jsoup.connect(currentUrl).userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36").timeout(5000).get();// 标记为已访问visitedUrls.add(currentUrl);// 提取页面中的所有链接Elements links = doc.select("a[href]");for (Element link : links) {String nextUrl = link.absUrl("href");// 只爬取同一域名下的URLif (nextUrl.contains(baseUrl) && !visitedUrls.contains(nextUrl)) {urlsToVisit.add(nextUrl);}}// 处理当前页面(这里只是打印标题)System.out.println("标题: " + doc.title());System.out.println("已爬取: " + visitedUrls.size() + " 个页面\n");// 休眠一秒,避免请求过于频繁Thread.sleep(1000);} catch (IOException | InterruptedException e) {System.out.println("爬取失败: " + currentUrl);System.out.println("错误: " + e.getMessage());}}System.out.println("爬取完成,共爬取了 " + visitedUrls.size() + " 个页面");}public static void main(String[] args) {// 创建爬虫实例,从指定URL开始,最多爬取20个页面SimpleCrawler crawler = new SimpleCrawler("https://www.baidu.com", 20);crawler.crawl();}
}

2.3 爬虫注意事项

在编写和使用网络爬虫时,需要注意以下几点:

  1. 尊重robots.txt:这是网站用来告诉爬虫哪些页面可以爬取,哪些不可以的文件。
  2. 控制爬取速度:不要在短时间内发送大量请求,这可能会被视为攻击行为。
  3. 识别自己:在请求头中设置合适的User-Agent,表明你的爬虫身份。
  4. 处理异常:网络爬虫可能会遇到各种异常情况,如连接超时、页面不存在等。
  5. 遵守法律法规:不要爬取和使用违反法律法规的内容。

3. 邮件发送

Java提供了JavaMail API来发送和接收电子邮件。在Java EE中,JavaMail是标准组件;在Java SE中,需要额外添加依赖。

3.1 JavaMail基础

想象一下:如果说普通的邮件客户端(如Outlook或Gmail)是我们用来发送邮件的工具,那么JavaMail就像是一个程序化的邮件助手,它可以按照我们的指令自动发送和接收邮件。

首先,我们需要添加JavaMail依赖。如果使用Maven,可以在pom.xml中添加:

<dependency><groupId>com.sun.mail</groupId><artifactId>javax.mail</artifactId><version>1.6.2</version>
</dependency>

如果不使用Maven,可以从JavaMail官网下载JAR文件并添加到项目的类路径中。

3.2 发送简单邮件

下面是一个发送简单文本邮件的例子:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;public class SendEmailDemo {public static void main(String[] args) {// 发件人邮箱和密码(或授权码)final String username = "your_email@example.com";final String password = "your_password_or_app_password";// 收件人邮箱String toEmail = "recipient@example.com";// 设置邮件服务器属性Properties props = new Properties();props.put("mail.smtp.auth", "true");props.put("mail.smtp.starttls.enable", "true");props.put("mail.smtp.host", "smtp.example.com");  // 如:smtp.gmail.comprops.put("mail.smtp.port", "587");  // 常用端口:587或465// 创建会话Session session = Session.getInstance(props, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(username, password);}});try {// 创建邮件消息Message message = new MimeMessage(session);message.setFrom(new InternetAddress(username));message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));message.setSubject("测试邮件");message.setText("你好,这是一封测试邮件!");// 发送邮件Transport.send(message);System.out.println("邮件发送成功!");} catch (MessagingException e) {System.out.println("邮件发送失败: " + e.getMessage());e.printStackTrace();}}
}

3.3 发送HTML邮件和附件

在实际应用中,我们可能需要发送HTML格式的邮件或带有附件的邮件:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;public class SendHtmlEmailWithAttachment {public static void main(String[] args) {// 发件人邮箱和密码(或授权码)final String username = "your_email@example.com";final String password = "your_password_or_app_password";// 收件人邮箱String toEmail = "recipient@example.com";// 设置邮件服务器属性Properties props = new Properties();props.put("mail.smtp.auth", "true");props.put("mail.smtp.starttls.enable", "true");props.put("mail.smtp.host", "smtp.example.com");props.put("mail.smtp.port", "587");// 创建会话Session session = Session.getInstance(props, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(username, password);}});try {// 创建邮件消息Message message = new MimeMessage(session);message.setFrom(new InternetAddress(username));message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));message.setSubject("HTML邮件测试");// 创建多部分消息Multipart multipart = new MimeMultipart();// 创建HTML内容部分MimeBodyPart htmlPart = new MimeBodyPart();String htmlContent = "<h1>你好</h1>" +"<p>这是一封<b>HTML格式</b>的测试邮件!</p>" +"<p>你可以在这里添加<a href='https://www.example.com'>链接</a>。</p>";htmlPart.setContent(htmlContent, "text/html; charset=utf-8");multipart.addBodyPart(htmlPart);// 创建附件部分MimeBodyPart attachmentPart = new MimeBodyPart();String filename = "test.txt";  // 附件文件路径attachmentPart.attachFile(filename);attachmentPart.setFileName("测试文件.txt");  // 附件显示的文件名multipart.addBodyPart(attachmentPart);// 设置邮件内容为多部分内容message.setContent(multipart);// 发送邮件Transport.send(message);System.out.println("HTML邮件(带附件)发送成功!");} catch (Exception e) {System.out.println("邮件发送失败: " + e.getMessage());e.printStackTrace();}}
}

3.4 使用第三方邮件服务

在实际应用中,我们通常会使用第三方邮件服务来发送邮件,如Gmail、QQ邮箱等。不同的邮件服务可能有不同的配置要求,下面是一些常见邮件服务的配置示例:

Gmail
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");

注意:使用Gmail发送邮件时,可能需要在Google账户设置中启用"不够安全的应用访问权限",或者使用应用专用密码。

QQ邮箱
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");  // QQ邮箱需要SSL
props.put("mail.smtp.host", "smtp.qq.com");
props.put("mail.smtp.port", "465");

注意:使用QQ邮箱发送邮件时,密码应该使用授权码,而不是QQ密码。可以在QQ邮箱设置中获取授权码。

总结

在本章的第二部分中,我们学习了Java网络编程的更多高级内容,包括HTTP客户端、网络爬虫入门和邮件发送。这些知识使我们能够开发更复杂、更实用的网络应用程序。

通过HTTP客户端,我们可以与Web服务器进行交互,获取和发送数据;通过网络爬虫,我们可以自动获取和分析网页内容;通过JavaMail,我们可以在应用程序中实现邮件发送功能。

这些技术在实际应用中非常有用,例如:开发Web API客户端、数据采集工具、自动化报告系统等。

练习

  1. 编写一个程序,使用HttpClient获取指定网页的内容,并统计页面中出现的特定单词的次数。
  2. 实现一个简单的网络爬虫,爬取某个新闻网站的最新新闻标题和链接。
  3. 编写一个程序,定时发送邮件报告系统状态(如CPU使用率、内存使用情况等)。
  4. 实现一个HTTP文件上传客户端,可以将本地文件上传到指定的服务器。
  5. 创建一个邮件客户端应用,支持发送HTML格式的邮件和添加多个附件。
http://www.xdnf.cn/news/225433.html

相关文章:

  • 数据资产管理与AI融合:物联网时代的新征程
  • 【KWDB 创作者计划】_存储引擎深度解析
  • 核心技能:ArcGIS洪水灾害普查、风险评估及淹没制图
  • MT6765 android上层获取VCM lens位置
  • macOS 安装了Docker Desktop版终端docker 命令没办法使用
  • ‌阿里云dns服务器不可用怎么办?dns可以随便改吗?
  • Dockerfile最佳实践:构建高效、安全的容器镜像
  • AI生成Flutter UI代码实践(一)
  • 学习记录:DAY21
  • EasyRTC嵌入式音视频实时通话SDK技术,打造低延迟、高安全的远程技术支持
  • 【JavaEE】网络原理之初识(1.0)
  • M1 Mac pip3 install错误记录
  • 算法基础学习|03整数二分
  • 【工具变量】地级市李白消费指数及预期指数数据集(2012-2022年)
  • Java学习手册:Spring 中常用的注解
  • day11 python超参数调整
  • 在若依前后端分离项目中集成 ONLYOFFICE 以实现在线预览、编辑和协作功能
  • 网页出现502的报错是什么意思?
  • 泰迪杯特等奖案例学习资料:基于多模态数据融合与边缘计算的工业设备健康监测与预测性维护系统
  • GPU集群中的超节点
  • 基于Q学习的2048游戏智能体:制作一个自己会玩游戏的智能体
  • CSS实现DIV水平与垂直居中方法总结
  • tailwindcss如何改变antd子组件的样式
  • CSS:选择器-复合选择器
  • RHCSA Linux 系统 文件系统权限
  • Linux——HTTP协议理解
  • 7.计算机网络相关术语
  • Axure疑难杂症:中继器制作下拉菜单(多级中继器高级交互)
  • 使用PyTorch进行热狗图像分类模型微调
  • 第四部分:实用应用开发