千家信息网

Spring5怎么配置WebClient

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,本篇内容主要讲解"Spring5怎么配置WebClient",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spring5怎么配置WebClient"吧!前言
千家信息网最后更新 2025年11月07日Spring5怎么配置WebClient

本篇内容主要讲解"Spring5怎么配置WebClient",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spring5怎么配置WebClient"吧!

前言

Spring5带来了新的响应式web开发框架WebFlux,同时,也引入了新的HttpClient框架WebClient。WebClient是Spring5中引入的执行 HTTP 请求的非阻塞、反应式客户端。它对同步和异步以及流方案都有很好的支持,WebClient发布后,RestTemplate将在将来版本中弃用,并且不会向前添加主要新功能。

WebClient与RestTemplate比较

WebClient是一个功能完善的Http请求客户端,与RestTemplate相比,WebClient支持以下内容:

  • 非阻塞 I/O。

  • 反应流背压(消费者消费负载过高时主动反馈生产者放慢生产速度的一种机制)。

  • 具有高并发性,硬件资源消耗更少。

  • 流畅的API设计。

  • 同步和异步交互。

  • 流式传输支持

HTTP底层库选择

Spring5的WebClient客户端和WebFlux服务器都依赖于相同的非阻塞编解码器来编码和解码请求和响应内容。默认底层使用Netty,内置支持Jetty反应性HttpClient实现。同时,也可以通过编码的方式实现ClientHttpConnector接口自定义新的底层库;如切换Jetty实现:

WebClient.builder()    .clientConnector(new JettyClientHttpConnector())    .build();

WebClient配置

基础配置

WebClient实例构造器可以设置一些基础的全局的web请求配置信息,比如默认的cookie、header、baseUrl等


WebClient.builder()    .defaultCookie("test","t1")    .defaultUriVariables(ImmutableMap.of("name","kl"))    .defaultHeader("header","kl")    .defaultHeaders(httpHeaders -> {      httpHeaders.add("header1","kl");      httpHeaders.add("header2","kl");    })    .defaultCookies(cookie ->{      cookie.add("cookie1","kl");      cookie.add("cookie2","kl");    })    .baseUrl("http://www.kailing.pub")    .build();
 

底层依赖Netty库配置

通过定制Netty底层库,可以配置SSl安全连接,以及请求超时,读写超时等。这里需要注意一个问题,默认的连接池最大连接500。获取连接超时默认是45000ms,你可以配置成动态的连接池,就可以突破这些默认配置,也可以根据业务自己制定。包括Netty的select线程和工作线程也都可以自己设置。

//配置动态连接池//ConnectionProvider provider = ConnectionProvider.elastic("elastic pool");//配置固定大小连接池,如最大连接数、连接获取超时、空闲连接死亡时间等ConnectionProvider provider = ConnectionProvider.fixed("fixed", 45, 4000, Duration.ofSeconds(6));HttpClient httpClient = HttpClient.create(provider)    .secure(sslContextSpec -> {      SslContextBuilder sslContextBuilder = SslContextBuilder.forClient()          .trustManager(new File("E://server.truststore"));      sslContextSpec.sslContext(sslContextBuilder);    }).tcpConfiguration(tcpClient -> {      //指定Netty的select 和 work线程数量      LoopResources loop = LoopResources.create("kl-event-loop", 1, 4, true);      return tcpClient.doOnConnected(connection -> {        //读写超时设置        connection.addHandlerLast(new ReadTimeoutHandler(10, TimeUnit.SECONDS))            .addHandlerLast(new WriteTimeoutHandler(10));      })          //连接超时设置          .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)          .option(ChannelOption.TCP_NODELAY, true)          .runOn(loop);    });WebClient.builder()    .clientConnector(new ReactorClientHttpConnector(httpClient))    .build();

编解码配置

针对特定的数据交互格式,可以设置自定义编解码的模式,如下:

ExchangeStrategies strategies = ExchangeStrategies.builder()    .codecs(configurer -> {      configurer.customCodecs().decoder(new Jackson2JsonDecoder());      configurer.customCodecs().encoder(new Jackson2JsonEncoder());    })    .build();WebClient.builder()    .exchangeStrategies(strategies)    .build();

get请求示例

uri构造时支持属性占位符,真实参数在入参时排序好就可以。同时可以通过accept设置媒体类型,以及编码。最终的结果值是通过Mono和Flux来接收的,在subscribe方法中订阅返回值。

WebClient client = WebClient.create("http://www.kailing.pub");Mono result = client.get()    .uri("/article/index/arcid/{id}.html", 256)    .acceptCharset(StandardCharsets.UTF_8)    .accept(MediaType.TEXT_HTML)    .retrieve()    .bodyToMono(String.class);result.subscribe(System.err::println);

如果需要携带复杂的查询参数,可以通过UriComponentsBuilder构造出uri请求地址,如:

//定义query参数MultiValueMap params = new LinkedMultiValueMap<>();params.add("name", "kl");params.add("age", "19");//定义url参数Map uriVariables = new HashMap<>();uriVariables.put("id", 200);String uri = UriComponentsBuilder.fromUriString("/article/index/arcid/{id}.html")

下载文件时,因为不清楚各种格式文件对应的MIME Type,可以设置accept为MediaType.ALL,然后使用Spring的Resource来接收数据即可,如:

WebClient.create("https://kk-open-public.oss-cn-shanghai.aliyuncs.com/xxx.xlsx")    .get()    .accept(MediaType.ALL)    .retrieve()    .bodyToMono(Resource.class)    .subscribe(resource -> {      try {        File file = new File("E://abcd.xlsx");        FileCopyUtils.copy(StreamUtils.copyToByteArray(resource.getInputStream()), file);      }catch (IOException ex){}    });

post请求示例

post请求示例演示了一个比较复杂的场景,同时包含表单参数和文件流数据。如果是普通post请求,直接通过bodyValue设置对象实例即可。不用FormInserter构造。

WebClient client = WebClient.create("http://www.kailing.pub");FormInserter formInserter = fromMultipartData("name","kl")    .with("age",19)    .with("map",ImmutableMap.of("xx","xx"))    .with("file",new File("E://xxx.doc"));Mono result = client.post()    .uri("/article/index/arcid/{id}.html", 256)    .contentType(MediaType.APPLICATION_JSON)    .body(formInserter)    //.bodyValue(ImmutableMap.of("name","kl"))    .retrieve()    .bodyToMono(String.class);result.subscribe(System.err::println);

同步返回结果

上面演示的都是异步的通过mono的subscribe订阅响应值。当然,如果你想同步阻塞获取结果,也可以通过.block()阻塞当前线程获取返回值。

WebClient client =  WebClient.create("http://www.kailing.pub");String result = client .get()    .uri("/article/index/arcid/{id}.html", 256)    .retrieve()    .bodyToMono(String.class)    .block();System.err.println(result);

但是,如果需要进行多个调用,则更高效地方式是避免单独阻塞每个响应,而是等待组合结果,如:

WebClient client =  WebClient.create("http://www.kailing.pub");Mono result1Mono = client .get()    .uri("/article/index/arcid/{id}.html", 255)    .retrieve()    .bodyToMono(String.class);Mono result2Mono = client .get()    .uri("/article/index/arcid/{id}.html", 254)    .retrieve()    .bodyToMono(String.class);Map  map = Mono.zip(result1Mono, result2Mono, (result1, result2) -> {  Map arrayList = new HashMap<>();  arrayList.put("result1", result1);  arrayList.put("result2", result2);  return arrayList;}).block();System.err.println(map.toString());

Filter过滤器

可以通过设置filter拦截器,统一修改拦截请求,比如认证的场景,如下示例,filter注册单个拦截器,filters可以注册多个拦截器,basicAuthentication是系统内置的用于basicAuth的拦截器,limitResponseSize是系统内置用于限制响值byte大小的拦截器

WebClient.builder()    .baseUrl("http://www.kailing.pub")    .filter((request, next) -> {      ClientRequest filtered = ClientRequest.from(request)          .header("foo", "bar")          .build();      return next.exchange(filtered);    })    .filters(filters ->{      filters.add(ExchangeFilterFunctions.basicAuthentication("username","password"));      filters.add(ExchangeFilterFunctions.limitResponseSize(800));    })    .build().get()    .uri("/article/index/arcid/{id}.html", 254)    .retrieve()    .bodyToMono(String.class)    .subscribe(System.err::println);

websocket支持

WebClient不支持websocket请求,请求websocket接口时需要使用WebSocketClient,如:

WebSocketClient client = new ReactorNettyWebSocketClient();URI url = new URI("ws://localhost:8080/path");client.execute(url, session ->    session.receive()        .doOnNext(System.out::println)        .then());

到此,相信大家对"Spring5怎么配置WebClient"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

配置 支持 阻塞 参数 可以通过 底层 拦截器 内容 同时 示例 线程 结果 同步 客户 客户端 数据 文件 编码 反应 复杂 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 u8帐套数据库还原 萤石云视频存储nas服务器连接 网络安全人才缺70万 黄浦区即时网络技术供应 边缘服务器说明什么 熊猫烧香网络安全案例 指导会员加强网络安全保护 英雄联盟手游联系不上服务器 外网访问内部服务器 网络安全员证能找什么工作 代码插数据库报错 数据库可以干多久 网络技术专业要精通的语言 帆软抓数据库信息 丰镇软件开发项目管理 智能养老平台软件开发 出租屋数据库课程设计 贵州视点科技数据通讯网络技术 公务员考试用什么数据库 新罗县网络安全进校园 软件工程专业对日软件开发 联合国商贸数据库查不到数据 收钱吧互联网科技有限公司 江西网络授时模块服务器云空间 广东python软件开发服务费 武汉电脑软件开发教程 微博怎么刷数据库 手机怎么管理服务器数据库 亚圣科技互联网规划师 维护网络安全 首先要知道
0