c await和java_blog/java/test/awaitility.zh.md at master · c-rainstorm/blog · GitHub

```java

AtomicInteger atomic = new AtomicInteger(0);

// Do some async stuff that eventually updates the atomic integer

await().untilAtomic(atomic, equalTo(1));

```

等待一个 AtomicBoolean 更简单:

```java

AtomicBoolean atomic = new AtomicBoolean(false);

// Do some async stuff that eventually updates the atomic boolean

await().untilTrue(atomic);

```

如果您正在使用 Adders,例如 [LongAdder](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/LongAdder.html),则Awaitility 可让您简单地等待使其达到一定的值:

```java

await().untilAdder(myLongAdder, equalTo(5L))

```

同样,如果使用累加器,例如 [LongAccumulator](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/LongAccumulator.html),则可以执行以下操作:

```java

await().untilAccumulator(myLongAccumulator, equalTo(5L))

```

##Advanced

使用100毫秒的轮询间隔,初始延迟为20毫秒,直到客户状态等于 “REGISTERED”。本示例还通过指定别名(“customer registration”)来使用命名的 await。如果您在同一测试中有多个 await,那么很容易找出哪个等待语句失败。

```java

with().pollInterval(ONE_HUNDERED_MILLISECONDS).and().with().pollDelay(20, MILLISECONDS).await("customer registration").until(

customerStatus(), equalTo(REGISTERED));

```

您还可以指定这样的别名:

```java

await().with().alias("my alias"). ..

```

要使用非固定的轮询间隔,请参考 [轮询间隔](#polling)文档。

##Lambdas

您可以在条件中使用 lambda 表达式:

```java

await().atMost(5, SECONDS).until(() -> userRepository.size() == 1);

```

或方法引用:

```java

await().atMost(5, SECONDS).until(userRepository::isNotEmpty);

```

或方法引用和 Hamcrest 匹配器的组合:

```java

await().atMost(5, SECONDS).until(userRepository::size, is(1));

```

您还可以使用谓词:

```java

await().atMost(5, SECONDS).until(userRepository::size, size -> size == 1);

```

有关示例,请参阅 [Jayway小组博客](http://www.jayway.com/2014/04/23/java-8-and-assertj-support-in-awaitility-1-6-0/")。

##Using AssertJ or Fest Assert

您可以使用 [AssertJ](http://joel-costigliola.github.io/assertj/)或 [Fest Assert](https://code.google.com/p/fest/) 代替 Hamcrest(实际上可以使用任何在出错时引发异常的第三方库)。

```java

await().atMost(5, SECONDS).untilAsserted(() -> assertThat(fakeRepository.getValue()).isEqualTo(1));

```

##Ignoring Exceptions

在条件评估期间忽略某些类型的异常有时很有用。例如,如果您在等待到达最终状态之前正在等待将异常作为中间状态抛出的事件。以Spring的 [SocketUtils](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/SocketUtils.html) 类为例,该类使您可以在给定范围查找 TCP 端口。如果在给定范围内没有端口可用,它将抛出异常。假设我们知道给定范围内的某些端口不可用,但我们要等待它们可用。这是一个示例,我们可以选择忽略“SocketUtils”引发的任何异常。例如:

```java

given().ignoreExceptions().await().until(() -> SocketUtils.findAvailableTcpPort(x,y));

```

这指示 Awaitility 在条件评估期间忽略所有捕获的异常。异常将被视为评估失败。与提供的异常类型匹配的异常,测试不会失败(除非超时)。您还可以忽略特定的异常:

```java

given().ignoreException(IllegalStateException.class).await().until(() -> SocketUtils.findAvailableTcpPort(x,y));

```

或使用 Hamcrest 匹配器:

```java

given().ignoreExceptionsMatching(instanceOf(RuntimeException.class)).await().until(() -> SocketUtils.findAvailableTcpPort(x,y));

```

或使用谓词(Java 8):

```java

given().ignoreExceptionsMatching(e -> e.getMessage().startsWith("Could not find an available")).await().until(something());

```

您也可以忽略 `Throwable` 实例。

##Checked exceptions in Runnable lambda expressions

Java中的 `Runnable` 接口不允许您抛出已检查的异常。因此,如果您有这样的方法:

```java

public void waitUntilCompleted() throws Exception { ... }

```

可能会引发异常,如果 `untilAsserted` 将 `Runnable` 作为其参数值,则您必须捕获该异常:

```java

await().untilAsserted(() -> {

try {

waitUntilCompleted();

} catch(Exception e) {

// Handle exception

}

});

```

幸运的是,Awaitility 通过引入传递给 `untilAsserted` 的 [ThrowingRunnable](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/core/ThrowingRunnable.html) 接口来解决此问题。而不是 `Runnable`。因此,您需要编写的代码如下所示:

```java

await().untilAsserted(() -> waitUntilCompleted());

```

##At Least

您可以指定 awaitility **最少** 等待一定时间。例如:

```java

await().atLeast(1, SECONDS).and().atMost(2, SECONDS).until(value(), equalTo(1));

```

如果在由 atLeast 指定的持续时间之前满足条件,则会引发异常,条件不应早于指定的时间完成。

###Ignoring uncaught exceptions

如果要将代码从使用 `Thread.sleep` 迁移到 Awaitility,请注意,在某些情况下,由于其他线程抛出异常,因此 Awaitility 测试用例可能会失败。这是因为默认情况下,Awaitility 捕获所有未捕获的异常。因此,如果您以前使用过 `Thread.sleep`,那么很有可能您没有捕获其他线程的异常。如果您对此行为感到满意,并且不希望 Awaitility 捕获这些异常,则可以使用 `dontCatchUncaughtExceptions` 禁用此功能:

```java

@Test

public void dontCatchUncaughtExample() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

executor.setMaxPoolSize(1);

executor.afterPropertiesSet();

executor.execute(new ErrorTestTask());

ListenableFuture> future = executor.submitListenable(new ErrorTestTask());

Awaitility.await()

.dontCatchUncaughtExceptions()

.atMost(1, TimeUnit.SECONDS)

.pollInterval(10, TimeUnit.MILLISECONDS)

.until(future::isDone);

}

private static class ErrorTestTask implements Runnable {

@Override

public void run() {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

throw new RuntimeException(Thread.currentThread().getName() + " -> Error");

}

}

```

###Assert that a value is maintained

从4.0.2版开始,可以断言某个值在特定时间段内得到维护。例如,如果您需要确保存储库中的值在 1500毫秒中的 800毫秒内保持特定值:

```java

await().during(800, MILLISECONDS).atMost(1500, MILLISECONDS).until(() -> myRepository.findById("id"), equalTo("something"));

```

Awaitility 将最多等待1500毫秒,而这样做的话,`myRepository.findById(id)` 必须等于 `something` 至少 800毫秒。

##Thread Handling

Awaitility 允许进行细粒度的线程配置。这是通过提供 Awaility 轮询条件时将使用的线程提供者或 `ExecutorService` 来完成的。请注意,这是一项高级功能,应谨慎使用。例如:

```java

given().pollThread(Thread::new).await().atMost(1000, MILLISECONDS).until(..);

```

另一种方法是指定 `ExecutorService`:

```java

ExecutorSerivce es = ...

given().pollExecutorService(es).await().atMost(1000, MILLISECONDS).until(..);

```

例如,如果您需要等待轮询 [ThreadLocal](https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html) 变量的条件,这将很有用。

在某些情况下,重要的是能够指示 Awaitility 使用与启动 Awaitility 的测试用例相同的线程。因此,Awaitility 3.0.0 引入了 [pollInSameThread](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/core/ConditionFactory.html#pollInSameThread--) 方法:

```java

with().pollInSameThread().await().atMost(1000, MILLISECONDS).until(...);

```

这是一项高级功能,在将 `pollInSameThread` 与永远等待(或长时间)的条件结合使用时应格外小心,因为当 Awaitility 使用与测试相同的线程时,它不会中断该线程。

## Exception handling

默认情况下,Awaitility 捕获所有线程中未捕获的 `Throwable`,并将其传播到等待线程。这意味着您的测试用例将指示失败,即使不是引发未捕获异常的测试线程也是如此。

您可以选择忽略某些异常或可抛出对象,请参见 [here](#ignoring-exceptions)。

如果不需要在所有线程中都捕获异常,则可以使用 [dontCatchUncaughtExceptions](#ignoring-uncaught-exceptions)。

## Deadlock detection

Awaitility自动检测死锁,并将 [ConditionTimeoutException](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/core/ConditionTimeoutException.html) 的原因与 [DeadlockException](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/core/DeadlockException.html)。 `DeadlockException` 包含有关导致死锁的线程的信息。

## Defaults

如果未指定任何超时,则 Awaitility 将等待10秒钟,然后引发 [ConditionTimeoutException](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/core/ConditionTimeoutException.html)(如果条件尚未满足)。默认轮询间隔和轮询延迟为100毫秒。您还可以自己使用以下命令指定默认值:

```java

Awaitility.setDefaultTimeout(..)

Awaitility.setDefaultPollInterval(..)

Awaitility.setDefaultPollDelay(..)

```

您还可以使用 `Awaitility.reset` 将其重置为默认值。

## Polling

请注意,由于 Awaitility 使用轮询来验证条件是否匹配,因此不建议将其用于精确的性能测试。在这些情况下,最好使用 AOP 框架,例如 AspectJ。

另请注意,[Duration.ZERO](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/Duration.html#ZERO) 用作所有非固定轮询间隔的起始值间隔。对于固定的轮询间隔,出于向后兼容的原因,轮询延迟等于 `FixedPollInterval` 的持续时间。

有关其他详细信息,请参见 [this blog](http://code.haleby.se/2015/11/27/non-fixed-poll-intervals-in-awaitility/)。

## Fixed Poll Interval

这是 Awaitilty 的默认轮询间隔机制。以正常方式使用DSL时,例如:

```java

with().pollDelay(100, MILLISECONDS).and().pollInterval(200, MILLISECONDS).await().until();

```

Awaitility 将使用 [FixedPollInterval](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/pollinterval/FixedPollInterval.html)。这意味着 Awaitility 将在 poll delay(轮询开始之前的初始延迟,在上面的示例中为100ms)之后首次检查是否满足指定条件。除非明确指定,否则 Awaitility 将使用与轮询间隔相同的轮询延迟(请注意,这仅适用于固定轮询间隔,如上例所示)。这意味着它将首先在给定的轮询延迟后定期检查条件,然后再以给定的轮询间隔进行检查;那就是在 pollDelay 之后检查条件,然后pollDelay + pollInterval,然后pollDelay +(2 *pollInterval),依此类推。如果更改轮询间隔,则轮询延迟也将更改为与指定的轮询间隔相匹配,除非您已明确指定了轮询延迟。

## Fibonacci Poll Interval

[FibonacciPollInterval](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/pollinterval/FibonacciPollInterval.html) 会根据斐波那契序列生成一个非线性轮询间隔。用法示例:

```java

with().pollInterval(fibonacci()).await().until(..);

```

其中的 `fibonacci()`是从 `org.awaitility.pollinterval.FibonacciPollInterval` 静态导入的。这将生成一个 "1、2、3、5、8、13,..." 毫秒的轮询间隔。您可以配置要使用的时间单位,例如秒而不是毫秒:

```java

with().pollInterval(fibonacci(TimeUnit.SECONDS)).await().until(..);

```

或使用 english-like 的配置方式

```java

with().pollInterval(fibonacci().with().timeUnit(SECONDS).and().offset(5)).await().until(..);

```

偏移量表示斐波那契序列从该偏移量开始(默认情况下,偏移量为0)。偏移量也可以是负数(-1)以0开头(`fib(0)`= 0)。

## Iterative Poll Interval

由函数和开始持续时间生成的轮询间隔。该函数可以在持续时间内自由地执行任何操作。

例如:

```java

await().with().pollInterval(iterative(duration -> duration.multiply(2)), Duration.FIVE_HUNDRED_MILLISECONDS).until(..);

```

或使用 english-like 的配置方式

```java

await().with().pollInterval(iterative(duration -> duration.multiply(2)).with().startDuration(FIVE_HUNDRED_MILLISECONDS)).until(..);

```

这将生成一个轮询间隔序列,看起来像这样(ms):`500,1000,2000,4000,8000,16000,...`

请注意,如果指定轮询初始延迟,则此延迟将在此轮询间隔生成第一个轮询间隔之前。有关更多信息,请参见[javadoc](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/pollinterval/IterativePollInterval.html)。

## Custom Poll Interval

通过实现 [PollInterval](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/pollinterval/PollInterval.html) 接口,可以滚动自己的轮询间隔。这是一个功能接口,因此在Java 8中,您可以像这样进行操作:

```java

await().with().pollInterval((__, previous) -> previous.multiply(2).plus(1)).until(..);

```

在此示例中,我们创建一个`PollInterval`,该函数被实现为(bi-)函数,该函数采用先前的轮询间隔持续时间并将其乘以2并加1。`__` 只是表示我们不在乎 [PollInterval](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/pollinterval/PollInterval.html) 提供的轮询计数。当创建的轮询间隔不是(仅)对前一个持续时间感兴趣,而是根据其被调用的次数生成其持续时间时,需要轮询计数。例如,[FibonacciPollInterval](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/pollinterval/FibonacciPollInterval.html) 仅使用轮询计数:

```java

await().with().pollInterval((pollCount, __) -> new Duration(fib(pollCount), MILLISECONDS)).until(..);

```

在大多数情况下,没有必要从头开始实施轮询间隔。改为向 [IterativePollInterval](#iterative-poll-interval) 提供函数。

## Condition Evaluation Listener

Awaitility 1.6.1引入了 [Condition Evaluation Listener](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/core/ConditionEvaluationListener.html) 的概念。每当 Awaitility 评估条件时,都可以使用它来获取信息。例如,您可以使用它来在条件满足之前获取条件的中间值。它也可以用于打印日志。例如:

```java

with().

conditionEvaluationListener(condition -> System.out.printf("%s (elapsed time %dms, remaining time %dms)\n", condition.getDescription(), condition.getElapsedTimeInMS(), condition.getRemainingTimeInMS())).

await().atMost(Duration.TEN_SECONDS).until(new CountDown(5), is(equalTo(0)));

```

将以下内容打印到控制台:

```java

org.awaitility.AwaitilityJava8Test$CountDown expected (<0> or a value less than <0>) but was <5> (elapsed time 101ms, remaining time 1899ms)

org.awaitility.AwaitilityJava8Test$CountDown expected (<0> or a value less than <0>) but was <4> (elapsed time 204ms, remaining time 1796ms)

org.awaitility.AwaitilityJava8Test$CountDown expected (<0> or a value less than <0>) but was <3> (elapsed time 306ms, remaining time 1694ms)

org.awaitility.AwaitilityJava8Test$CountDown expected (<0> or a value less than <0>) but was <2> (elapsed time 407ms, remaining time 1593ms)

org.awaitility.AwaitilityJava8Test$CountDown expected (<0> or a value less than <0>) but was <1> (elapsed time 508ms, remaining time 1492ms)

org.awaitility.AwaitilityJava8Test$CountDown reached its end value of (<0> or a value less than <0>) (elapsed time 610ms, remaining time 1390ms)

```

有一个内置的用于记录日志的 ConditionEvaluationListener,名为 [ConditionEvaluationLogger](http://static.javadoc.io/org.awaitility/awaitility/4.0.2/org/awaitility/core/ConditionEvaluationLogger.html) 可以像这样使用:

```java

with().conditionEvaluationListener(new ConditionEvaluationLogger()).await(). ...

```

Awaitility 4.0.2在 `ConditionEvaluationListener` 接口中引入了三个新的 hook(默认方法):

| Method | Description |

| ------------------ |-------------|

| `beforeEvaluation` | 在条件评估之前调用 |

| `exceptionIgnored` | 处理条件评估时引发的被忽略异常 |

| `onTimeout` | 当条件超时时调用 |

## Duration

Awaitility提供了一个 [Duration](http://static.javadoc.io/org.awaitility/awaitility/1.6.5/org/awaitility/Duration.html) 类,其中包含一些预定义的持续时间值,例如 `ONE_HUNDRED_MILLISECONDS`,`FIVE_SECONDS` 和 `ONE_MINUTE`。您还可以在 `Duration` 实例上执行一些基本的数学运算。例如:

```java

new Duration(5, SECONDS).plus(17, MILLISECONDS);

```

它将返回新的持续时间5017毫秒。请注意,持续时间是不可变的,因此调用 `plus` 将返回一个新实例。当使用非固定的 [轮询间隔](#polling) 时这个比较有用。

## Important

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实现输入框小数多 自动进位展示,编辑时实际值不变

今天遇到个业务需求&#xff0c;要求输入框&#xff0c;输入数字的小数位数可以很多位&#xff0c;但移开后显示&#xff0c;只显示小数点后两位 &#xff08;四舍五入&#xff09;&#xff0c;当要编辑的时候&#xff0c;展现其原来的输入数据。 闲话不多说&#xff0c;当时也…

使用Jasper Reports以Java创建报告

上周&#xff0c;我试图使用Jasper创建报告。 在这篇文章中&#xff0c;我将记录一些资源和链接&#xff0c;以便对任何寻求类似信息的人都有用。 我将介绍Jasper报告&#xff0c;示例和Dynamic Jasper的生命周期。 Jasper Reports是世界上最受欢迎的开源报告引擎。 它完全用…

CentOS7 安装NodeJS

一、切换目录到/usr/local/src 命令行&#xff1a;cd /usr/local/src 二、下载node.js&#xff08;我这里下载的是二进制的源码&#xff09; 命令行&#xff1a; wget https://nodejs.org/dist/v8.9.1/node-v8.9.1-linux-x64.tar.xz 图片&#xff1a; 三、解压压缩包 命令行&am…

CSS3基础2(变形与动画)

<!DOCTYPE html5><html lang"en"><head> <meta charset"UTF-8"> <title>CSS3基础知识&#xff08;动画&#xff09;</title> <style> /*div{*/ /*width: 150px;*/ /*hei…

java对hashmap迭代_Java:通过HashMap迭代,这样更有效率?

第二个选项肯定更有效&#xff0c;因为在第一个选项中只进行一次查找&#xff0c;次数为n次。但是&#xff0c;没有什么比尝试它更好&#xff0c;当你可以。所以这里 –(不完美&#xff0c;但足够好验证假设和我的机器)public static void main(String args[]) {Map map new H…

html-edm(邮件营销)编写规则

最近写了一个edm邮件 以前没有接触过 使用的是很老的html页面编写规则 只能用table标签 在此记录一下edm编写的一些规则 个人参考的是这两个网址&#xff0c;转载一下 http://www.zcool.com.cn/article/ZMTM5MDgw.html https://www.cnblogs.com/lhweb15/p/6404626.html …

ASP.NET Core2.0 环境下MVC模式的支付宝PC网站支付接口-沙箱环境开发测试

1.新建.NET Core web项目 2.Controllers-Models-Views 分三个大部分 3.下载安装最新sdk 官方的SDK以及Demo都还是.NET Framework的&#xff0c;根据官方文档说明新建网站后还是需要引用官方SDK的源码&#xff0c; 在这里直接使用网上一位朋友的用.NET Standard 2.0 进行实现了支…

如何在redhat8里使用gcc命令_如何使用who命令检查用户登录信息

请关注本头条号&#xff0c;每天坚持更新原创干货技术文章。如需学习视频&#xff0c;请在微信搜索公众号“智传网优”直接开始自助视频学习1. 前言本教程主要介绍如何使用who命令检查用户登录信息。如何使用who命令检查用户登录信息Linux中的who命令列出了系统上的所有登录用户…

研究僵局–第4部分:修复代码

在这个简短的博客系列的最后BadTransferOperation中&#xff0c;我一直在讨论分析死锁&#xff0c;我将修复BadTransferOperation代码。 如果您看过本系列的其他博客 &#xff0c;那么您将知道&#xff0c;为了达到这一点&#xff0c;我创建了死锁的演示代码&#xff0c;展示了…

chrome插件2

转自&#xff1a;http://www.codeceo.com/article/15-chrome-extension.html 1. Web Developer 支持Chrome的Web Developer扩展&#xff0c;允许你通过添加一个小工具栏来使用不同的工具。 官方网站&#xff1a;https://chrome.google.com/webstore/detail/web-developer/bfbam…

java月历组件_vue之手把手教你写日历组件

---恢复内容开始---1.日历组件1.分析功能&#xff1a;日历基本功能&#xff0c;点击事件改变日期&#xff0c;样式的改变1.结构分析&#xff1a;html1.分为上下两个部分2.上面分为左按钮&#xff0c;中间内容展示&#xff0c;右按钮下面分为周几展示和日期展示3.基本结构页面ht…

HTML5和css3

超链接 <a target"页面打开位置" href"链接地址">内容</a>target:_blank 重新打开一个页面target:_self 当前页面打开 1.页面地址&#xff1a; 基础功能&#xff0c;用于进入该链接的页面&#xff1b; 2.锚点&#xff1a; 需要给标签名定义id…

python下载显示文件丢失_Microsoft.PythonTools.resources.dll

我该如何安装从金山毒霸下载的DLL文件&#xff1f;一&#xff1a;1、从金山毒霸下载压缩文件。2、将DLL文件解压到电脑上的某个地方。3、把该文件跟要求使用它的程序放在同一路径上。注意32位程序需要使用32位的DLL文件&#xff0c;64位程序需要使用64位的DLL文件。否则会出现0…

maven project module 依赖项目创建 ---转

一、创建Maven Project 1.右击 --> New --> Other&#xff0c;--> Maven --> Maven Project --> Next 2.如下图&#xff0c;选中Create a simple project --> Next 3.输入Group Id, Artifact Id, Version, Packaging选择pom&#xff0c;因为创建的Maven Pr…

java soot_正确执行3个地址代码的SOOT API

我在运行SOOT API时遇到问题 . 我正在使用java -cp soot-2.5.0.jar soot.Main -f jimple test我遇到以下错误&#xff1a;Exception in thread "main" java.lang.RuntimeException: Could not load classfile: java.io.ObjectInputStream atat soot.coffi.Util.resol…

JSF AJAX请求的会话超时处理

JSF AJAX请求的会话超时处理 当我们使用AJAX行为开发JSF应用程序时&#xff0c;在处理Ajax请求超时场景时可能会遇到问题。 例如&#xff0c;如果您使用的是基于J2EE表单的身份验证&#xff0c;则会话超时后应将正常请求重定向到登录页面。 但是&#xff0c;如果您的请求是AJAX…

linux常见命令搜集

查找根目录下txt和pdf文件 find / \( -name "*.txt" -o -name "*.pdf" \) -print 正则查找根目录下所有的txt和pdf文件 find / -regex ".*\(\.txt|\.pdf\)$"查找所有非txt文本 find . ! -name "*.txt" -print制定搜索深度 find ~ -max…

前端html,css基础总结

0.1、css引入界面的方式: 内联式:通过标签的style属性&#xff0c;在标签上直接写样式。 <div style"width:100px; height:100px; background:red "></div> 嵌入式:通过style标签&#xff0c;在网页上创建嵌入的样式表。 <style type"text/css&q…

知乎python练手的_Python—爬虫之初级实战项目:爬取知乎任一作者的文章练手

爬虫之初级实战项目&#xff1a;爬取知乎任一作者的文章练手在正式上代码之前&#xff0c;先过一遍之前所学知识的框架内容&#xff0c;温故而知新&#xff01;&#xff01;&#xff01;接下来我们直接上代码&#xff0c;一定要手敲代码、手敲代码、手敲代码&#xff01;&#…

java url帮助类_Spring居然还提供了这么好用的URL工具类

1. 前言开发中我们经常会操作 URL&#xff0c;比如提取端口、提取路径以及最常用的提取参数等等。很多时候需要借助于一些第三方类库或者自己编写工具类来实现&#xff0c;今天胖哥给大家介绍一种方法&#xff0c;无需新的类库引入&#xff0c;只要你使用了 Spring Web 模块都可…