赞
踩
WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具,从Spring5.0开始WebClient作为RestTemplete的替代品,有更好的响应式能力,支持异步调用,可以在Spring项目中实现网络请求。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.fly</groupId> <artifactId>web-client</artifactId> <version>0.0.1</version> <name>base</name> <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> </plugins> </build> </project>
log4j2.xml
<?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:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</console>
</appenders>
<loggers>
<root level="INFO">
<appender-ref ref="Console" />
</root>
</loggers>
</configuration>
FluxWebClient.java
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> * * https://blog.csdn.net/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("https://00fly.online/upload/urls.txt").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()); } }
RunMain.java
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 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <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="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.fly.http.RunWebClient</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> //goto src\main\java\com\fly\http\FluxWebClient.java 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> * * https://blog.csdn.net/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("https://00fly.online/upload/urls.txt").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\RunMain.java 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\log4j2.xml <?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:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </console> </appenders> <loggers> <root level="INFO"> <appender-ref ref="Console" /> </root> </loggers> </configuration>
有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!
-over-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。