最简WebClient 同步、异步调用示例
//goto
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0"
xmlns:xsi="http:///2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fly</groupId>
<artifactId>web-client</artifactId>
<version>0.0.1</version>
<name>web-client</name>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>0.9.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<filters>
<filter>
<artifact>*:*</artifact>
</filter>
</filters>
<transformers>
<!--
往MANIFEST文件中写入Main-Class是可执行包的必要条件。ManifestResourceTransformer可以轻松实现。 -->
<transformer
implementation="">
<mainClass>com.fly.http.RunWebClient</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
//goto src\main\java\com\fly\http\
package com.fly.http;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import lombok.extern.slf4j.Slf4j;
/**
* WebClient是RestTemplete的替代品,有更好的响应式能力,支持异步调用<br>
*
* /zzhongcy/article/details/105412842
*
*/
@Slf4j
public class FluxWebClient
{
private List<String> urls = new ArrayList<>();
// 缓冲区默认256k,设为-1以解决报错Exceeded limit on max bytes to buffer : 262144
private WebClient webClient = WebClient.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)).build();
public void visitAll()
{
// block转换为同步调用
if (urls.isEmpty())
{
String resp = webClient.get().uri("/upload/").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.TEXT_HTML).retrieve().bodyToMono(String.class).block();
urls = Arrays.asList(StringUtils.split(resp, "\r\n"));
log.info("★★★★★★★★ urls:");
urls.stream().forEach(log::info);
}
// 异步访问
AtomicInteger count = new AtomicInteger(0);
urls.stream()
.filter(url -> RandomUtils.nextBoolean())
.forEach(url -> webClient.get()
.uri(url)
.acceptCharset(StandardCharsets.UTF_8)
.accept(MediaType.TEXT_HTML)
.retrieve()
.bodyToMono(String.class)
.subscribe(r -> log.info("process complted: {}. {}", count.incrementAndGet(), url), e -> log.error(e.getMessage())));
log.info("total:{} ==> ############## 异步请求已提交 ##############", urls.size());
}
}
//goto src\main\java\com\fly\http\
package com.fly.http;
import java.util.Timer;
import java.util.TimerTask;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RunMain
{
/**
* 程序运行入口
*
* @param args
*/
public static void main(String[] args)
{
// Timer线程安全, 但单线程执行, 抛出异常时, task会终止
FluxWebClient webClient = new FluxWebClient();
new Timer().scheduleAtFixedRate(new TimerTask()
{
@Override
public void run()
{
webClient.visitAll();
}
}, 0L, 30 * 1000L);
log.info("======== Timer started!");
}
}
//goto src\main\resources\
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="off" monitorInterval="0">
<appenders>
<console name="Console" target="system_out">
<patternLayout pattern="%d{yyyy-MM-dd HH:mm:} [%t] %-5level %logger{36} - %msg%n" />
</console>
</appenders>
<loggers>
<root level="INFO">
<appender-ref ref="Console" />
</root>
</loggers>
</configuration>