您现在的位置是:首页 > 名人名句

最简WebClient 同步、异步调用示例

作者:焦糖时间:2024-03-22 17:35:35分类:名人名句

简介  文章浏览阅读1.4w次。WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具,从Spring5.0开始WebClient作为RestTemplete的替代品,有更好的响应式能力,支持异步调用,可以在

点击全文阅读

目录

一,序言二,简单示例1. 引入依赖2. 日志配置3. 调用代码4. 运行结果 三,完整代码

一,序言

WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具,从Spring5.0开始WebClient作为RestTemplete的替代品,有更好的响应式能力,支持异步调用,可以在Spring项目中实现网络请求。

二,简单示例

1. 引入依赖

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>

2. 日志配置

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>

3. 调用代码

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 *  */@Slf4jpublic 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;@Slf4jpublic 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!");    }}

4. 运行结果

在这里插入图片描述

三,完整代码

如何使用下面的备份文件恢复成原始的项目代码,请移步查阅:神奇代码恢复工具

//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可以轻松实现。 --><transformerimplementation="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.javapackage 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 *  */@Slf4jpublic 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.javapackage com.fly.http;import java.util.Timer;import java.util.TimerTask;import lombok.extern.slf4j.Slf4j;@Slf4jpublic 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-

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句