Java 中文官方教程 2022 版(四十五)(3)

简介: Java 中文官方教程 2022 版(四十五)

Java 中文官方教程 2022 版(四十五)(2)https://developer.aliyun.com/article/1488409

运行程序

你必须先启动服务器程序。为此,请使用 Java 解释器运行服务器程序,就像运行任何其他 Java 应用程序一样。指定服务器程序监听的端口号作为命令行参数:

java KnockKnockServer 4444

接下来,运行客户端程序。请注意,你可以在网络上的任何计算机上运行客户端;它不必在与服务器相同的计算机上运行。指定运行KnockKnockServer服务器程序的计算机的主机名和端口号作为命令行参数:

java KnockKnockClient knockknockserver.example.com 4444

如果你太快了,可能会在服务器有机会初始化并开始监听端口之前启动客户端。如果发生这种情况,你将会看到客户端的堆栈跟踪。如果发生这种情况,只需重新启动客户端。

如果在第一个客户端连接到服务器时尝试启动第二个客户端,第二个客户端将会挂起。下一节,支持多个客户端,讨论了支持多个客户端的问题。

当客户端和服务器成功建立连接时,你将在屏幕上看到以下文本显示:

Server: Knock! Knock!

现在,你必须回复:

Who's there?

客户端会回显你输入的内容并将文本发送到服务器。服务器会回复其中一个众多“敲敲”笑话的第一行。现在你的屏幕应该显示如下内容(你输入的文本用粗体表示):

Server: Knock! Knock!
Who's there?
Client: Who's there?
Server: Turnip

现在,你回复:

Turnip who?

再次,客户端会回显你输入的内容并将文本发送到服务器。服务器会回复一个笑话的结尾。现在你的屏幕应该显示如下内容:

Server: Knock! Knock!
Who's there?
Client: Who's there?
Server: Turnip
Turnip who?
Client: Turnip who?
Server: Turnip the heat, it's cold in here! Want another? (y/n)

如果你想听另一个笑话,输入y;如果不想,输入n。如果输入y,服务器会重新开始“敲敲”;如果输入n,服务器会说“再见”,导致客户端和服务器都退出。

如果在任何时候你打错字,KnockKnockServer对象会捕捉到并回复类似于这样的消息:

Server: You're supposed to say "Who's there?"!

然后服务器会重新开始讲笑话:

Server: Try again. Knock! Knock!

注意,KnockKnockProtocol对象对拼写和标点符号很在意,但对大小写不在意。

支持多个客户端

为了保持KnockKnockServer示例简单,我们设计它来监听并处理单个连接请求。然而,多个客户端请求可以进入同一端口,因此也进入同一个ServerSocket。客户端连接请求在端口处排队,因此服务器必须按顺序接受连接。然而,服务器可以通过使用线程同时为它们提供服务——每个客户端连接一个线程。

这样一个服务器的基本逻辑流程是这样的:

while (true) {
    accept a connection;
    create a thread to deal with the client;
}

线程根据需要从客户端连接读取和写入。


试一试:

修改KnockKnockServer以便能够同时为多个客户端提供服务。我们的解决方案由两个类组成:KKMultiServerKKMultiServerThreadKKMultiServer永远循环,监听ServerSocket上的客户端连接请求。当有请求进来时,KKMultiServer接受连接,创建一个新的KKMultiServerThread对象来处理它,将从 accept 返回的套接字传递给它,并启动线程。然后服务器继续监听连接请求。KKMultiServerThread对象通过读取和写入套接字与客户端通信。运行新的“敲敲”服务器KKMultiServer,然后依次运行几个客户端。


教训:关于数据报的一切

原文:docs.oracle.com/javase/tutorial/networking/datagrams/index.html

您编写的一些用于在网络上通信的应用程序不需要 TCP 提供的可靠的点对点通道。相反,您的应用程序可能会从一种通信模式中受益,该模式传递独立的信息包,其到达和到达顺序不受保证。

UDP 协议提供了一种网络通信模式,应用程序可以向彼此发送数据包,称为数据报。数据报是通过网络发送的独立、自包含的消息,其到达、到达时间和内容均不受保证。java.net包中的DatagramPacketDatagramSocket类使用 UDP 实现了系统独立的数据报通信。

什么是数据报?

数据报是通过网络发送的独立、自包含的消息,其到达、到达时间和内容均不受保证。

编写数据报客户端和服务器

本节将通过一个示例引导您,其中包含两个使用数据报进行通信的 Java 程序。服务器端是一个引用服务器,它监听其DatagramSocket并在客户端请求时向客户端发送引用。客户端是一个简单的程序,只需向服务器发出请求。

向多个接收方广播

本节修改引用服务器,使其不再在请求时向单个客户端发送引用,而是每分钟向所有正在侦听的客户端广播一条引用。客户端程序必须相应地进行修改。


注意:

许多防火墙和路由器被配置为不允许 UDP 数据包。如果您在防火墙外部连接到服务时遇到问题,或者客户端无法连接到您的服务,请向系统管理员询问是否允许 UDP。


什么是数据报?

原文:docs.oracle.com/javase/tutorial/networking/datagrams/definition.html

客户端和服务器通过可靠的通道(如 TCP 套接字)进行通信,它们之间有一个专用的点对点通道,或者至少有这种幻觉。为了通信,它们建立连接,传输数据,然后关闭连接。所有通过通道发送的数据都按照发送顺序接收。这由通道保证。

相反,通过数据报通信的应用程序发送和接收完全独立的信息包。这些客户端和服务器没有也不需要专用的点对点通道。数据报的传递到目的地不被保证。它们的到达顺序也不被保证。


定义:

一个数据报是独立的、自包含的消息,通过网络发送,其到达、到达时间和内容都不被保证。


java.net包含三个类,帮助你编写使用数据报在网络上传输和接收数据包的 Java 程序:DatagramSocketDatagramPacketMulticastSocket。一个应用程序可以通过DatagramSocket发送和接收DatagramPacket。此外,DatagramPacket可以广播到多个接收者,所有接收者都监听MulticastSocket

编写数据报客户端和服务器

原文:docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html

本节中展示的示例由两个应用程序组成:客户端和服务器。服务器持续接收数据报包,每个数据报包都表示客户端请求报价。当服务器接收到数据报时,它会通过数据报包将一行“此刻引用”发送回客户端。

本示例中的客户端应用程序非常简单。它向服务器发送一个数据报包,指示客户端希望接收此刻引用。然后客户端等待服务器发送数据报包作为响应。

两个类实现了服务器应用程序:QuoteServerQuoteServerThread。一个类实现了客户端应用程序:QuoteClient

让我们从包含服务器应用程序的main方法的类开始研究这些类。使用服务器端应用程序包含QuoteClient类的小程序版本。

引用服务器类

在这里完整显示的QuoteServer类包含一个方法:引用服务器应用程序的main方法。main方法只是创建一个新的QuoteServerThread对象并启动它:

import java.io.*;
public class QuoteServer {
    public static void main(String[] args) throws IOException {
        new QuoteServerThread().start();
    }
}

QuoteServerThread 类实现了引用服务器的主要逻辑。

QuoteServerThread

创建时,QuoteServerThread在端口 4445 上创建了一个DatagramSocket(任意选择)。这是服务器与所有客户端通信的DatagramSocket

public QuoteServerThread() throws IOException {
    this("QuoteServer");
}
public QuoteServerThread(String name) throws IOException {
    super(name);
    socket = new DatagramSocket(4445);
    try {
        in = new BufferedReader(new FileReader("one-liners.txt"));
    }   
    catch (FileNotFoundException e){
        System.err.println("Couldn't open quote file.  Serving time instead.");
    }
}

请记住,某些端口专用于已知服务,您不能使用它们。如果指定一个正在使用的端口,DatagramSocket的创建将失败。

构造函数还在名为one-liners.txt的文件上打开了一个BufferedReader,其中包含引用列表。文件中的每个引用都在单独的一行上。

现在来看QuoteServerThread的有趣部分:它的run方法。run方法覆盖了Thread类中的run方法,并为线程提供了实现。有关线程的信息,请参见定义和启动线程。

run 方法包含一个while循环,只要文件中还有更多引用,循环就会继续。在循环的每次迭代中,线程会等待一个DatagramPacket通过DatagramSocket到达。数据包表示客户端的请求。作为对客户端请求的响应,QuoteServerThread从文件中获取引用,将其放入DatagramPacket中,并通过DatagramSocket将其发送到请求的客户端。

让我们首先看一下接收客户端请求的部分:

byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);

第一条语句创建了一个字节数组,然后用它创建了一个DatagramPacketDatagramPacket将用于从套接字接收数据报,因为使用了创建它的构造函数。这个构造函数只需要两个参数:一个包含客户端特定数据的字节数组和字节数组的长度。在构造要通过DatagramSocket发送的DatagramPacket时,还必须提供数据包目的地的互联网地址和端口号。当我们讨论服务器如何响应客户端请求时,你会看到这一点。

前一个代码片段中的最后一条语句从套接字接收一个数据报(从客户端接收的信息被复制到数据包中)。receive方法会一直等待,直到接收到一个数据包。如果没有接收到数据包,服务器将不会有进一步的进展,只会等待。

现在假设,服务器收到了客户端请求报价的请求。现在服务器必须做出响应。run方法中的这部分代码构建了响应:

String dString = null;
if (in == null)
    dString = new Date().toString();
else
    dString = getNextQuote();
buf = dString.getBytes();

如果由于某种原因未打开报价文件,则in等于 null。如果是这种情况,报价服务器将提供当天的时间。否则,报价服务器从已打开的文件中获取下一个报价。最后,代码将字符串转换为字节数组。

现在,run方法使用以下代码向客户端通过DatagramSocket发送响应:

InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);

这段代码中的前两条语句分别从客户端接收的数据报中获取了互联网地址和端口号。互联网地址和端口号指示了数据报包的来源。这是服务器必须发送响应的地方。在这个例子中,数据报包的字节数组不包含相关信息。根据报包的到达本身就表示了来自互联网地址和端口号所指示的客户端的请求。

第三条语句创建了一个新的DatagramPacket对象,用于通过数据报套接字发送数据报消息。你可以通过创建它的构造函数来判断新的DatagramPacket是用于通过套接字发送数据的。这个构造函数需要四个参数。前两个参数与用于创建接收数据报的构造函数相同:包含从发送方到接收方的消息的字节数组和该数组的长度。接下来的两个参数不同:一个互联网地址和一个端口号。这两个参数是数据报包的目的地的完整地址,必须由数据报的发送方提供。最后一行代码将DatagramPacket发送出去。

当服务器从报价文件中读取了所有报价后,while循环终止,run方法进行清理:

socket.close();

QuoteClient 类

QuoteClient类实现了QuoteServer的客户端应用程序。此应用程序向QuoteServer发送请求,等待响应,并在接收到响应时将其显示到标准输出。让我们详细看看代码。

QuoteClient类包含一个方法,即客户端应用程序的main方法。main方法的顶部声明了几个局部变量供其使用:

int port;
InetAddress address;
DatagramSocket socket = null;
DatagramPacket packet;
byte[] sendBuf = new byte[256];

首先,main方法处理用于调用QuoteClient应用程序的命令行参数:

if (args.length != 1) {
    System.out.println("Usage: java QuoteClient <hostname>");
    return;
}

QuoteClient应用程序需要一个命令行参数:运行QuoteServer的机器的名称。

接下来,main方法创建一个DatagramSocket

DatagramSocket socket = new DatagramSocket();

客户端使用一个不需要端口号的构造函数。此构造函数只是将DatagramSocket绑定到任何可用的本地端口。客户端绑定到的端口号并不重要,因为DatagramPacket包含寻址信息。服务器从DatagramPacket中获取端口号并将其响应发送到该端口。

接下来,QuoteClient程序向服务器发送一个请求:

byte[] buf = new byte[256];
InetAddress address = InetAddress.getByName(args[0]);
DatagramPacket packet = new DatagramPacket(buf, buf.length, 
                                address, 4445);
socket.send(packet);

代码段获取命令行上命名的主机的 Internet 地址(假设服务器运行的机器的名称)。然后使用此InetAddress和端口号 4445(服务器用于创建其DatagramSocket的端口号)创建一个发送到该 Internet 地址和端口号的DatagramPacket。因此,DatagramPacket将被传递到引用服务器。

请注意,代码创建了一个带有空字节数组的DatagramPacket。字节数组为空,因为此数据报包仅仅是向服务器请求信息。服务器发送响应所需的所有信息—地址和端口号—自动包含在数据包中。

接下来,客户端从服务器获取响应并显示出来:

packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Quote of the Moment: " + received);

要从服务器获取响应,客户端创建一个“接收”数据包,并使用DatagramSocket的接收方法从服务器接收回复。接收方法会等待直到一个发送给客户端的数据包通过套接字传输过来。请注意,如果服务器的回复某种原因丢失,客户端将永远等待,因为数据报模型没有保证策略。通常,客户端会设置一个计时器,以便不会永远等待回复;如果没有收到回复,计时器会触发,客户端会重新发送。

当客户端从服务器接收到回复时,客户端使用getData方法从数据包中检索数据。然后客户端将数据转换为字符串并显示出来。

运行服务器和客户端

在成功编译服务器和客户端程序之后,您可以运行它们。必须先运行服务器程序。只需使用 Java 解释器并指定QuoteServer类名。

一旦服务器启动,你可以运行客户端程序。记得用一个命令行参数来运行客户端程序:QuoteServer运行的主机名。

当客户端发送请求并从服务器接收到响应后,你应该看到类似于以下输出:

Quote of the Moment:
Good programming is 99% sweat and 1% coffee.

向多个接收者广播

原文:docs.oracle.com/javase/tutorial/networking/datagrams/broadcasting.html

除了DatagramSocket,它让程序之间可以发送数据包,java.net 还包括一个名为MulticastSocket的类。这种类型的套接字用于客户端监听服务器广播给多个客户端的数据包。

让我们重写引用服务器,使其可以向多个接收者广播DatagramPacket。而不是向请求的特定客户端发送引用,新服务器现在需要定期广播引用。客户端需要进行修改,以便被动地监听引用,并在MulticastSocket上这样做。

这个示例由三个类组成,这三个类是前一个示例中三个类的修改版本:MulticastServerMulticastServerThread,和MulticastClient。本讨论重点介绍了这些类的有趣部分。

这是服务器主程序的新版本。这段代码与之前版本QuoteServer的不同之处用粗体显示出来:

import java.io.*;
public class MulticastServer {
    public static void main(String[] args) throws IOException {
        new MulticastServerThread().start();
    }
}

基本上,服务器得到了一个新的名称,并创建了一个MulticastServerThread而不是QuoteServerThread。现在让我们看看MulticastServerThread,其中包含服务器的核心。这是它的类声明:

public class MulticastServerThread extends QuoteServerThread {
    // ...
}

我们将这个类作为QuoteServerThread的子类,以便它可以使用构造函数,并继承一些成员变量和getNextQuote方法。回想一下,QuoteServerThread创建了一个绑定到端口 4445 的DatagramSocket并打开引用文件。在这个示例中,DatagramSocket的端口号实际上并不重要,因为客户端从不向服务器发送任何内容。

MulticastServerThread中唯一显式实现的方法是其run方法。这个run方法与QuoteServerThread中的方法的不同之处用粗体显示出来:

public void run() {
    while (moreQuotes) {
        try {
            byte[] buf = new byte[256];
            // don't wait for request...just send a quote
            String dString = null;
            if (in == null)
                dString = new Date().toString();
            else
                dString = getNextQuote();
            buf = dString.getBytes();
            InetAddress group = InetAddress.getByName("203.0.113.0");
            DatagramPacket packet;
            packet = new DatagramPacket(buf, buf.length, group, 4446);
            socket.send(packet);
            try {
                sleep((long)Math.random() * FIVE_SECONDS);
            } 
            catch (InterruptedException e) { }
        }
        catch (IOException e) {
            e.printStackTrace();
            moreQuotes = false;
        }
    }
    socket.close();
}

有趣的变化是如何构造DatagramPacket,特别是用于构造DatagramPacketInetAddress和端口。回想一下,前一个示例从客户端发送到服务器的数据包中检索了InetAddress和端口号。这是因为服务器需要直接回复给客户端。现在,服务器需要向多个客户端发送数据。因此,这次InetAddress和端口号都是硬编码的。

硬编码的端口号是 4446(客户端必须将MulticastSocket绑定到此端口)。DatagramPacket的硬编码InetAddress是"203.0.113.0",是一个组标识符(而不是单个客户端所在机器的互联网地址)。这个特定地址是从保留给此目的的地址中任意选择的。

以这种方式创建的DatagramPacket将发送到所有监听端口号为 4446 且属于"203.0.113.0"组的客户端。

要监听端口号 4446,新创建的客户端程序只需使用该端口号创建其MulticastSocket。要成为"203.0.113.0"组的成员,客户端调用MulticastSocketjoinGroup方法,并提供标识该组的InetAddress。现在,客户端已设置好接收发送到指定端口和组的DatagramPacket。以下是新客户端程序中相关的代码(还对其进行了重写,以 passively 接收引用而不是主动请求)。粗体语句是与MulticastSocket交互的语句:

MulticastSocket socket = new MulticastSocket(4446);
InetAddress group = InetAddress.getByName("203.0.113.0");
socket.joinGroup(group);
DatagramPacket packet;
for (int i = 0; i < 5; i++) {
    byte[] buf = new byte[256];
    packet = new DatagramPacket(buf, buf.length);
    socket.receive(packet);
    String received = new String(packet.getData());
    System.out.println("Quote of the Moment: " + received);
}
socket.leaveGroup(group);
socket.close();

注意,服务器使用DatagramSocket广播客户端接收的DatagramPacket,而客户端使用MulticastSocket。或者,它可以使用MulticastSocket。服务器用于发送DatagramPacket的套接字并不重要。在广播数据包时重要的是DatagramPacket中包含的寻址信息,以及客户端用于监听的套接字


试试这个:

运行MulticastServer和几个客户端。观察客户端如何都收到相同的引用。


课程:程序化访问网络参数

原文:docs.oracle.com/javase/tutorial/networking/nifs/index.html

系统通常会同时运行多个活动网络连接,比如有线以太网,802.11 b/g(无线)和蓝牙。一些应用程序可能需要访问这些信息,以便在特定连接上执行特定的网络活动。

java.net.NetworkInterface 类提供了访问这些信息的途径。

本课程将指导您了解此类的一些常见用法,并提供列出机器上所有网络接口及其 IP 地址和状态的示例。

什么是网络接口?

本页面描述了一个网络接口,并解释了为什么您可能想要使用它。

检索网络接口

本页面包含一个示例,演示了客户端程序如何检索机器上的所有网络接口。

列出网络接口地址

本页面向您展示如何列出分配给机器上所有网络接口的 IP 地址。

网络接口参数

本页面向您展示如何确定网络接口是否正在运行,或者网络接口是环回接口、点对点接口还是虚拟接口。您还可以了解如何确定接口是否支持多播。

什么是网络接口?

原文:docs.oracle.com/javase/tutorial/networking/nifs/definition.html

网络接口是计算机与私有或公共网络之间的连接点。网络接口通常是网络接口卡(NIC),但不一定要有物理形式。相反,网络接口可以在软件中实现。例如,环回接口(IPv4 的127.0.0.1和 IPv6 的::1)不是物理设备,而是模拟网络接口的软件部分。环回接口通常用于测试环境。

java.net.NetworkInterface类代表两种类型的接口。

NetworkInterface对于具有多个 NIC 的多宿主系统非常有用。使用NetworkInterface,您可以指定要用于特定网络活动的 NIC。

例如,假设您有一台配置了两个 NIC 的机器,并且您想向服务器发送数据。您可以这样创建一个套接字:

Socket soc = new java.net.Socket();
soc.connect(new InetSocketAddress(address, port));

发送数据时,系统会确定使用哪个接口。但是,如果您有偏好或需要指定要使用的 NIC,您可以查询系统以找到适当的接口并在您想要使用的接口上找到一个地址。当您创建套接字并将其绑定到该地址时,系统将使用相关联的接口。例如:

NetworkInterface nif = NetworkInterface.getByName("bge0");
Enumeration<InetAddress> nifAddresses = nif.getInetAddresses();
Socket soc = new java.net.Socket();
soc.bind(new InetSocketAddress(nifAddresses.nextElement(), 0));
soc.connect(new InetSocketAddress(address, port));

您还可以使用NetworkInterface来识别要加入多播组的本地接口。例如:

NetworkInterface nif = NetworkInterface.getByName("bge0");
MulticastSocket ms = new MulticastSocket();
ms.joinGroup(new InetSocketAddress(hostname, port), nif);

NetworkInterface可以与 Java API 一起以许多其他方式使用,超出了此处描述的两种用途。

检索网络接口

原文:docs.oracle.com/javase/tutorial/networking/nifs/retrieving.html

NetworkInterface 类没有公共构造函数。因此,您不能只使用new运算符创建此类的新实例。相反,提供了以下静态方法,以便您可以从系统中检索接口详细信息:getByInetAddress()getByName()getNetworkInterfaces()。前两种方法用于当您已经知道特定接口的 IP 地址或名称时。第三种方法,getNetworkInterfaces() 返回计算机上所有接口的完整列表。

网络接口可以按层次结构组织。NetworkInterface 类包括两个方法,getParent()getSubInterfaces(),这些方法与网络接口层次结构相关。getParent() 方法返回接口的父NetworkInterface。如果网络接口是子接口,则getParent() 返回一个非空值。getSubInterfaces() 方法返回网络接口的所有子接口。

以下示例程序列出了计算机上所有网络接口和子接口(如果存在)的名称。

import java.io.*;
import java.net.*;
import java.util.*;
import static java.lang.System.out;
public class ListNIFs 
{
    public static void main(String args[]) throws SocketException {
        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
        for (NetworkInterface netIf : Collections.list(nets)) {
            out.printf("Display name: %s\n", netIf.getDisplayName());
            out.printf("Name: %s\n", netIf.getName());
            displaySubInterfaces(netIf);
            out.printf("\n");
        }
    }
    static void displaySubInterfaces(NetworkInterface netIf) throws SocketException {
        Enumeration<NetworkInterface> subIfs = netIf.getSubInterfaces();
        for (NetworkInterface subIf : Collections.list(subIfs)) {
            out.printf("\tSub Interface Display name: %s\n", subIf.getDisplayName());
            out.printf("\tSub Interface Name: %s\n", subIf.getName());
        }
     }
}  

以下是示例程序的样本输出:

Display name: bge0
Name: bge0
    Sub Interface Display name: bge0:3
    Sub Interface Name: bge0:3
    Sub Interface Display name: bge0:2
    Sub Interface Name: bge0:2
    Sub Interface Display name: bge0:1
    Sub Interface Name: bge0:1
Display name: lo0
Name: lo0

Java 中文官方教程 2022 版(四十五)(4)https://developer.aliyun.com/article/1488414

相关文章
|
15天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(二十九)-java+ selenium自动化测试- Actions的相关操作上篇(详解教程)
【4月更文挑战第21天】本文介绍了Selenium中处理特殊测试场景的方法,如鼠标悬停。Selenium的Actions类提供了鼠标悬停功能,用于模拟用户在网页元素上的悬停行为。文中通过实例展示了如何使用Actions悬停并展开下拉菜单,以及在搜索时选择自动补全的字段。代码示例包括了打开百度首页,悬停在“更多”元素上显示下拉菜单并点击“音乐”,以及在搜索框输入关键词并自动补全的过程。
38 0
|
8天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
【4月更文挑战第28天】本文简要介绍了自动化测试的实战应用,通过一个在线问卷调查(&lt;https://www.sojump.com/m/2792226.aspx/&gt;)为例,展示了如何遍历并点击问卷中的选项。测试思路包括找到单选和多选按钮的共性以定位元素,然后使用for循环进行点击操作。代码设计方面,提供了Java+Selenium的示例代码,通过WebDriver实现自动答题。运行代码后,可以看到控制台输出和浏览器的相应动作。文章最后做了简单的小结,强调了本次实践是对之前单选多选操作的巩固。
22 0
|
1天前
|
JavaScript 前端开发 测试技术
《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)
【5月更文挑战第2天】在自动化测试过程中,经常会遇到处理日期控件的点击问题。宏哥之前分享过一种方法,但如果输入框是`readonly`属性,这种方法就无法奏效了。不过,通过修改元素属性,依然可以实现自动化填写日期。首先,定位到日期输入框并移除`readonly`属性,然后使用`sendKeys`方法输入日期。这样,即使输入框设置了`readonly`,也能成功处理日期控件。
13 1
|
2天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十七)-java+ selenium自动化测试-日历时间控件-上篇(详解教程)
【5月更文挑战第1天】该文介绍了使用Selenium自动化测试网页日历控件的方法。首先,文章提到在某些Web应用中,日历控件常用于选择日期并筛选数据。接着,它提供了两个实现思路:一是将日历视为文本输入框,直接输入日期;二是模拟用户交互,逐步选择日期。文中给出了JQueryUI网站的一个示例,并展示了对应的Java代码实现,包括点击日历、选择日期等操作。
13 0
|
8天前
|
Java 测试技术 项目管理
Java基础教程(22)-构建工具Maven的基本使用
【4月更文挑战第22天】Maven是Java项目管理及构建工具,简化构建、测试、打包和部署等任务。遵循约定优于配置原则,核心是`pom.xml`配置文件,用于管理依赖和项目信息。安装涉及下载、解压、配置环境变量。在IDEA中使用Maven创建项目,通过`pom.xml`添加依赖和管理版本。常用命令包括`clean`、`compile`、`test`、`package`、`install`和`deploy`。IDEA支持直接执行这些命令。
|
8天前
|
NoSQL Java 关系型数据库
Java基础教程(21)-Java连接MongoDB
【4月更文挑战第21天】MongoDB是开源的NoSQL数据库,强调高性能和灵活性。Java应用通过MongoDB Java驱动与之交互,涉及MongoClient、MongoDatabase、MongoCollection和Document等组件。连接MongoDB的步骤包括:配置连接字符串、创建MongoClient、选择数据库和集合。伪代码示例展示了如何建立连接、插入和查询数据。
|
9天前
|
存储 前端开发 测试技术
《手把手教你》系列技巧篇(三十五)-java+ selenium自动化测试-单选和多选按钮操作-下篇(详解教程)
【4月更文挑战第27天】本文介绍了使用Java+Selenium进行Web自动化测试时,如何遍历和操作多选按钮的方法。文章分为两个部分,首先是一个本地HTML页面的示例,展示了多选按钮的HTML代码和页面效果,并详细解释了遍历多选按钮的思路:找到所有多选按钮的共同点,通过定位这些元素并放入list容器中,然后使用for循环遍历并操作。 第二部分介绍了在JQueryUI网站上的实战,给出了被测网址,展示了代码设计,同样使用了findElements()方法获取所有多选按钮并存储到list中,然后遍历并进行点击操作。最后,文章对整个过程进行了小结,并推荐了作者的其他自动化测试教程资源。
18 0
|
9天前
|
Java 关系型数据库 MySQL
Java基础教程(20)-Java连接mysql数据库CURD
【4月更文挑战第19天】MySQL是流行的关系型数据库管理系统,支持SQL语法。在IDEA中加载jar包到项目类路径:右击项目,选择“Open Module Settings”,添加库文件。使用JDBC连接MySQL,首先下载JDBC驱动,然后通过`Class.forName()`加载驱动,`DriverManager.getConnection()`建立连接。执行CRUD操作,例如创建表、插入数据和查询,使用`Statement`或`PreparedStatement`,并确保正确关闭数据库资源。
|
10天前
|
设计模式 算法 Java
Java基础教程(19)-设计模式简述
【4月更文挑战第19天】设计模式是软件设计中反复使用的代码设计经验,旨在提升代码的可重用性、可扩展性和可维护性。23种模式分为创建型、结构型和行为型三类。创建型模式如工厂方法、抽象工厂、建造者、原型和单例,关注对象创建与使用的分离。结构型模式涉及对象组合,如适配器、装饰器、外观等,增强结构灵活性。行为型模式专注于对象间职责分配和算法合作,包括责任链、命令、观察者等。设计模式提供标准化解决方案,促进代码交流和复用。
|
11天前
|
前端开发 测试技术 Python
《手把手教你》系列技巧篇(三十三)-java+ selenium自动化测试-单选和多选按钮操作-上篇(详解教程)
【4月更文挑战第25天】本文介绍了自动化测试中如何处理单选和多选按钮的操作,包括它们的定义、HTML代码示例以及如何判断和操作这些元素。文章通过一个简单的HTML页面展示了单选和多选框的示例,并提供了Java+Selenium实现的代码示例,演示了如何检查单选框是否选中以及如何进行全选操作。
17 0