欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中WebClient的創(chuàng)建和使用詳解

 更新時間:2023年11月18日 09:06:29   作者:morris131  
這篇文章主要介紹了Spring中WebClient的創(chuàng)建和使用詳解,在Spring5中,出現(xiàn)了Reactive響應式編程思想,并且為網(wǎng)絡編程提供相關響應式編程的支持,如提供了WebFlux,它是Spring提供的異步非阻塞的響應式的網(wǎng)絡框架,需要的朋友可以參考下

前言

在Spring5中,出現(xiàn)了Reactive響應式編程思想,并且為網(wǎng)絡編程提供相關響應式編程的支持,如提供了WebFlux,它是Spring提供的異步非阻塞的響應式的網(wǎng)絡框架,相比傳統(tǒng)的SpringMVC框架,可以充分利用多CPU并行處理一些功能,雖然不能提高單個請求的響應能力,但是總體可以提高多核的服務器性能,提高系統(tǒng)吞吐量和伸縮性,特別適合于IO密集型服務。

WebClient提供的基于響應式的非阻塞的Web請求客戶端,相對于傳統(tǒng)的RestTemplate,他不阻塞代碼、異步執(zhí)行。

使用WebClient需要引入下面的依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

WebClient的創(chuàng)建

WebClient可以直接通過new來創(chuàng)建,也可以使用構造者模式來構造。

package com.morris.user.demo;

import com.morris.user.entity.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * WebClient的創(chuàng)建
 */
public class WebClientDemo1 {

    public static void main(String[] args) throws InterruptedException {
        WebClient webClient = WebClient.create();
        webClient.get().uri("http://127.0.0.1:8020/order/findOrderByUserId?userId={userId}", 1).retrieve()
                .bodyToMono(Order[].class).map(Arrays::asList).subscribe(System.out::println);

        WebClient webClient2 = WebClient.builder()
                .baseUrl("http://127.0.0.1:8020")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
        webClient2.get().uri("/order/findOrderByUserId?userId={userId}", 1).retrieve()
                .bodyToMono(Order[].class).map(Arrays::asList).subscribe(System.out::println);
        TimeUnit.SECONDS.sleep(5);
    }
}

在應用中使用WebClient時也許你要訪問的URL都來自同一個應用,只是對應不同的URI地址,這個時候可以把公用的部分抽出來定義為baseUrl,然后在進行WebClient請求的時候只指定相對于baseUrl的URL部分即可。這樣的好處是你的baseUrl需要變更的時候可以只要修改一處即可。

WebClient發(fā)送Get請求

先創(chuàng)建個webclient.create()實例,之后調用get()、post()等調用方式,uri()指定路徑,retrieve()用來發(fā)起請求并獲得響應,bodyToFlux(Order.class)用來將請求結果需要處理為Order數(shù)組,并包裝為Reactor的Flux對象。

如果返回結果是一個JSON字符串,可以使用bodyToMono(),將接收到的JSON字符串轉換為對應的對象。

如果返回結果是一個JSON數(shù)組,可以使用bodyToFlux(),將接收到的JSON數(shù)組轉換為對應的對象集合,然后依次處理每一個元素。

package com.morris.user.demo;

import com.morris.user.entity.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * WebClient發(fā)送Get請求
 */
public class WebClientGetDemo {

    public static void main(String[] args) throws InterruptedException {
        WebClient webClient = WebClient.create();
        webClient.get().uri("http://127.0.0.1:8020/order/findOrderByUserId?userId={userId}", 1).retrieve()
                .bodyToFlux(Order.class).subscribe(System.out::println);;

        // 休眠一會,否則WebClient中的線程池還沒執(zhí)行,看不到效果
        TimeUnit.SECONDS.sleep(5);
    }
}

WebClient發(fā)送Post請求

可以使用BodyInserters類提供的各種工廠方法來構造BodyInserter對象并將其傳遞給body方法。BodyInserters類包含從Object,Publisher,Resource,F(xiàn)ormData,MultipartData等創(chuàng)建BodyInserter的方法。

package com.morris.user.demo;

import com.morris.user.entity.Order;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * WebClient發(fā)送Post請求
 */
public class WebClientPostDemo {

    public static void main(String[] args) {
        WebClient webClient = WebClient.create();
        Order order = new Order();
        order.setId(1L);
        order.setUserId(666L);
        order.setGoodName("Iphone 13");
        order.setPrice(9999);
        Mono<Long> mono = webClient.post().uri("http://127.0.0.1:8020/order/saveOrder")
                .body(BodyInserters.fromValue(order))
                // .body(Mono.just(order), Order.class)
                .retrieve()
                .bodyToMono(Long.class);

        // 阻塞等待獲取結果
        System.out.println(mono.block());
    }
}

WebClient對失敗的處理

package com.morris.user.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;

/**
 * WebClient對失敗的處理
 */
@Slf4j
public class WebClientDealFailDemo {

    public static void main(String[] args) {
        WebClient webClient = WebClient.create();
        WebClient.ResponseSpec responseSpec = webClient.get().uri("http://127.0.0.1:8020/order/error")
                .retrieve();

        Mono<String> mono = responseSpec
                .onStatus(HttpStatus::is4xxClientError, resp -> {
                    log.error("error4xx:{},msg:{}",resp.statusCode().value(),resp.statusCode().getReasonPhrase());
                    return Mono.error(new RuntimeException(resp.statusCode().value() + " : " + resp.statusCode().getReasonPhrase()));
                })
                .bodyToMono(String.class)
                .doOnError(WebClientResponseException.class, err -> {
                    log.info("ERROR status:{},msg:{}",err.getRawStatusCode(),err.getResponseBodyAsString());
                    throw new RuntimeException(err.getMessage());
                })
                .onErrorReturn("fallback");

        // 阻塞等待獲取結果
        System.out.println(mono.block());
    }
}

可以使用onStatus根據(jù)響應的status code進行適配,可以使用doOnError對異常進行適配,可以使用onErrorReturn返回默認值。

exchange()

retrieve()方法是直接獲取響應body,但是,如果需要響應的頭信息、Cookie等,可以使用exchange方法,該方法可以訪問整個ClientResponse。由于響應的得到是異步的,所以都可以調用block()方法來阻塞當前程序,等待獲得響應的結果。

package com.morris.user.demo;

import com.morris.user.entity.Order;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.concurrent.TimeUnit;

/**
 * WebClient使用Exchange發(fā)送請求
 */
public class WebClientExchangeDemo {

    public static void main(String[] args) throws InterruptedException {
        WebClient webClient = WebClient.create();
        webClient.get().uri("http://127.0.0.1:8020/order/findOrderByUserId?userId={userId}", 1)
                .exchange()
                .subscribe(r -> {
                    System.out.println(r.headers());
                    r.bodyToFlux(Order.class).subscribe(System.out::println);
                });

        // 休眠一會,否則WebClient中的線程池還沒執(zhí)行,看不到效果
        TimeUnit.SECONDS.sleep(5);
    }
}

filter

WebClient也提供了Filter,對應于org.springframework.web.reactive.function.client.ExchangeFilterFunction接口,可以攔截request,也可以攔截response。

package com.morris.user.demo;

import com.morris.user.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.concurrent.TimeUnit;

/**
 * WebClient使用filter攔截器
 */
@Slf4j
public class WebClientFilterDemo {

    private static ExchangeFilterFunction logResponseStatus() {
        return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
            log.info("Response Status {}", clientResponse.statusCode());
            return Mono.just(clientResponse);
        });
    }

    public static void main(String[] args) throws InterruptedException {
        WebClient webClient = WebClient.builder().filter(logResponseStatus()).build();
        webClient.get().uri("http://127.0.0.1:8020/order/findOrderByUserId?userId={userId}", 1)
                .exchange()
                .subscribe(r -> {
                    System.out.println(r.headers());
                    r.bodyToFlux(Order.class).subscribe(System.out::println);
                });

        // 休眠一會,否則WebClient中的線程池還沒執(zhí)行,看不到效果
        TimeUnit.SECONDS.sleep(5);
    }
}

Attributes

可以使用attribute在多個filter之間傳遞參數(shù)。

package com.morris.user.demo;

import com.morris.user.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * WebClient使用attribute傳遞參數(shù)
 */
@Slf4j
public class WebClientAttributesDemo {

    private static ExchangeFilterFunction filterRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            Optional<Object> myAttribute = clientRequest.attribute("myAttribute");
            System.out.println(myAttribute.get());
            return Mono.just(clientRequest);
        });
    }

    public static void main(String[] args) throws InterruptedException {
        WebClient webClient = WebClient.builder().filter(filterRequest()).build();
        webClient.get().uri("http://127.0.0.1:8020/order/findOrderByUserId?userId={userId}", 1)
                .attribute("myAttribute", "myAttribute")
                .exchange()
                .subscribe(r -> {
                    System.out.println(r.headers());
                    r.bodyToFlux(Order.class).subscribe(System.out::println);
                });

        // 休眠一會,否則WebClient中的線程池還沒執(zhí)行,看不到效果
        TimeUnit.SECONDS.sleep(5);
    }
}

到此這篇關于Spring中WebClient的創(chuàng)建和使用詳解的文章就介紹到這了,更多相關WebClient的創(chuàng)建和使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Springboot中useGeneratedKeys用法小結

    Springboot中useGeneratedKeys用法小結

    本文主要介紹了Springboot中useGeneratedKeys用法小結,useGeneratedKeys?是 MyBatis 框架中的一個參數(shù),用于指定是否允許 JDBC 支持自動生成主鍵,感興趣的可以了解一下
    2024-09-09
  • Java16 JDK安裝并設置環(huán)境變量的方法步驟

    Java16 JDK安裝并設置環(huán)境變量的方法步驟

    突然想起自己大學剛接觸java的時候,要下載JDK和配置環(huán)境變量,那時候我上網(wǎng)找了很多教學,本文就詳細的介紹一下Java16 JDK安裝并設置環(huán)境變量,感興趣的可以了解一下
    2021-09-09
  • Java實戰(zhàn)之仿天貓商城系統(tǒng)的實現(xiàn)

    Java實戰(zhàn)之仿天貓商城系統(tǒng)的實現(xiàn)

    這篇文章主要介紹了如何利用Java制作一個基于SSM框架的迷你天貓商城系統(tǒng),文中采用的技術有JSP、Springboot、SpringMVC、Spring等,需要的可以參考一下
    2022-03-03
  • 深入淺析springsecurity入門登錄授權

    深入淺析springsecurity入門登錄授權

    SpringSecurity為我們提供了基于注解的權限控制方案,這也是我們項目中主要采用的方式,我們可以使用注解去指定訪問對應的資源所需的權限,這篇文章主要介紹了springsecurity入門登錄授權,需要的朋友可以參考下
    2024-05-05
  • 關于maven項目中使用BCrypt加密方式

    關于maven項目中使用BCrypt加密方式

    BCrypt是一種基于Blowfish加密算法的密碼散列函數(shù),用于安全存儲和驗證用戶密碼,它通過引入鹽和工作因子增加計算復雜度,有效防止彩虹表攻擊和破解,BCrypt具備適應性工作因子、成本參數(shù)調整、迭代哈希和密鑰擴展等特點,被廣泛應用于Web應用程序的安全性設計中
    2024-10-10
  • jackson 如何將實體轉json json字符串轉實體

    jackson 如何將實體轉json json字符串轉實體

    這篇文章主要介紹了jackson 實現(xiàn)將實體轉json json字符串轉實體,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Springboot并發(fā)調優(yōu)之大事務和長連接

    Springboot并發(fā)調優(yōu)之大事務和長連接

    這篇文章主要介紹了Springboot并發(fā)調優(yōu)之大事務和長連接,重點分享長事務以及長連接導致的并發(fā)排查和優(yōu)化思路和示例,具有一定的參考價值,感興趣的可以了解一下
    2022-05-05
  • Springboot實現(xiàn)多文件上傳代碼解析

    Springboot實現(xiàn)多文件上傳代碼解析

    這篇文章主要介紹了Springboot實現(xiàn)多文件上傳代碼解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • 解決IDEA2020.1.2IDEA打不開的問題(最新分享)

    解決IDEA2020.1.2IDEA打不開的問題(最新分享)

    由于idea安裝多了某個jar,點擊出現(xiàn)讀條后閃退情況,接下來通過本文給大家分享解決IDEA2020.1.2IDEA打不開的問題,非常不錯,具有一定的參考借鑒價值,感興趣的朋友跟隨小編一起看看吧
    2020-07-07
  • Spring AI內置DeepSeek的詳細步驟

    Spring AI內置DeepSeek的詳細步驟

    Spring AI 最新快照版已經內置 DeepSeek 了,所以以后項目中對接 DeepSeek 就方便多了,但因為快照版會有很多 Bug,所以今天咱們就來看穩(wěn)定版的 Spring AI 如何對接 DeepSeek 滿血版,感興趣的小伙伴跟著小編一起來看看吧
    2025-02-02

最新評論