使用WebClient发起网络请求

目录

1、导入对应的pom

2、编写WebClientUtil请求工具类

3、使用WebClientUtil发起请求


使用WebClient的优点:支持lambdas 的函数;支持更高的并发性和更少的硬件资源;支持同步和异步;支持流式传输。具体的使用方式如下:

1、导入对应的pom

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>3.2.4</version>
</dependency>

其中版本可以选择当前最新即可!

2、编写WebClientUtil请求工具类

(当然此步骤非必须,可以直接在需要发起请求的地方直接定义发起也可以)


import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * Web 客户端实用程序
 *
 * @author xjs
 * @date 2024/03/25
 */
public class WebClientUtil {

    private static final WebClient WEB_CLIENT = WebClient.create();
    // 默认JSON格式
    //private static final WebClient WEB_CLIENT = WebClient.builder().defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).build();


//==============================================================================================================================

    /**
     * 发起GET请求,支持Get parameter
     */
    public static CompletableFuture<String> getParam(String url, HttpHeaders headers, MultiValueMap<String, String> queryParams) {
        return Mono.from(WEB_CLIENT.get()
                        .uri(uriBuilder -> uriBuilder
                                .path(url)
                                .queryParams(queryParams)
                                .build())
                        .headers(httpHeaders -> httpHeaders.putAll(headers))
                        //.headers(h -> headers.forEach(h::add))
                        .retrieve()
                        .onStatus(HttpStatus::isError, clientResponse -> Mono.error(new RuntimeException("HTTP error status: " + clientResponse.statusCode())))
                        .bodyToMono(String.class))
                .onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息
                .toFuture();
    }

    /**
     * 发起GET请求,支持Get parameter
     * 可以用
     */
    public static CompletableFuture<String> getNoParam(String url, HttpHeaders headers) {
        return Mono.from(WEB_CLIENT.get()
                        .uri(url)
                        .headers(httpHeaders -> httpHeaders.putAll(headers))
                        //.headers(h -> headers.forEach(h::add))
                        .retrieve()
                        .onStatus(HttpStatus::isError, clientResponse -> Mono.error(new RuntimeException("HTTP error status: " + clientResponse.statusCode())))
                        .bodyToMono(String.class))
                .onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息
                .toFuture();
    }


    /**
     * 发起POST请求,支持JSON body
     */
    public static CompletableFuture<String> postJson2(String url, Object body, HashMap<String, String> headers) {
        logRequest();
        return Mono.from(WEB_CLIENT.post()
                        .uri(url)
                        .contentType(MediaType.APPLICATION_JSON)
                        .headers(h -> headers.forEach(h::add))
                        .bodyValue(body)
                        .retrieve()
                        .onStatus(HttpStatus::isError, clientResponse -> Mono.error(new RuntimeException("HTTP error status: " + clientResponse.statusCode())))
                        .bodyToMono(String.class))
                .onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息
                .toFuture();
    }

    /**
     * 发起POST请求,支持表单数据
     */
    public static CompletableFuture<String> postForm(String url, MultiValueMap<String, String> formData, Map<String, String> headers) {
        return Mono.from(WEB_CLIENT.post()
                        .uri(url)
                        .headers(h -> headers.forEach(h::add))
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .body(BodyInserters.fromFormData(formData))
                        .retrieve()
                        .bodyToMono(String.class))
                .toFuture();
    }

    


//===========方法2======================================================================================================

    public static <T> Mono<ResponseEntity<T>> sendRequest(String url, HttpMethod method, HashMap<String, String> headers, Object requestBody, Class<T> responseType) {
        return WEB_CLIENT.method(method)
                .uri(url)
                .headers(h -> headers.forEach(h::add))
                .body(BodyInserters.fromValue(requestBody))
                .retrieve()
                .toEntity(responseType);
    }

    public static CompletableFuture<String> postJson2(String url, Object body, HashMap<String, String> headers) {
        return sendRequest(url, HttpMethod.POST, headers, body, String.class)
                .doOnError(error -> System.err.println("An error occurred: " + error.getMessage()))
                .filter(entity -> entity.getStatusCode().is2xxSuccessful()) // 检查状态码是否成功
                .mapNotNull(ResponseEntity::getBody)
                .onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息
                .toFuture();
    }

//===========方法3============================================================================================================================================================
    private String baseUrl = "http://192.168.31.118:8091";
    WebClient webClient = WebClient.builder()
            .baseUrl(baseUrl)
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            // 使用了ExchangeStrategies来限制默认的解码器缓冲区的大小。这有助于避免处理大型响应时的内存问题。
            .exchangeStrategies(ExchangeStrategies.builder()
                    .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
                    .build())
            .build();


    /**
     * put 请求
     *
     * @param url         网址
     * @param requestBody 请求正文
     * @return {@link Mono}<{@link String}>
     */
    public Mono<String> putRequest(String url, Object requestBody) {
        return webClient.put()
                .uri(url)
                .body(BodyInserters.fromValue(requestBody))
                .retrieve()
                .bodyToMono(String.class);
    }

    /**
     * 删除请求
     *
     * @param url 网址
     * @return {@link Mono}<{@link String}>
     */
    public Mono<String> deleteRequest(String url) {
        return webClient.delete()
                .uri(url)
                .retrieve()
                .bodyToMono(String.class);
    }




}

3、使用WebClientUtil发起请求

    /**
	* 获取配置中的请求地址
	*/
	@Value("${url.baseUrl}")
    private String baseUrl;

	
	//发起POST请求
	@PostMapping("/postRequest")
    public Object postRequest(@RequestBody RequestParms requestParms) {
        // 设置请求头信息
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        CompletableFuture<String> postResponse = WebClientUtil.postJson(baseUrl, requestParms, headers);

        // 异步处理响应
        postResponse.thenAccept(response -> {
            log.info("response: {}", response);
            if (response.contains("code")) {
                try {
                    JSONObject postResponseJson = JSONObject.parseObject(response);
                    int statusCode = postResponseJson.getIntValue("code");
                    log.info("statusCode = " + statusCode);
                    JSONArray data = postResponseJson.getJSONArray("data");
                    log.info("data = " + data);
                } catch (Exception e) {
                    log.info("Failed to parse JSON: " + e.getMessage());
                }
            } else {
                log.info("No 'code' field in the response: " + response);
            }
        });

        return postResponse;

    }

	//发起GET请求
    @GetMapping("/getRequest")
    public Object getRequest(RequestParms requestParms) {
        // 创建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", "application/json, text/javascript, */*; q=0.01");
        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36");
        // 创建请求参数
        MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
        queryParams.add("code", requestParms.getCode());
		// 构建URL地址
        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(url);
        uriBuilder.queryParams(queryParams);
        String newUrls = String.valueOf(uriBuilder.build().toUri());

        // 发送GET请求
		//CompletableFuture<String> getResponse = WebClientUtil.getParam(url, headers, queryParams);
        CompletableFuture<String> getResponse = WebClientUtil.getNoParam(newUrls, headers);
        getResponse.thenAccept(response -> {
            log.info("response: {}", response);
            if (response.contains("status")) {
                try {
                    JSONObject postResponseJson = JSONObject.parseObject(response);
                    String status = postResponseJson.getString("status");
                    log.info("status = " + status);
                    JSONObject data = postResponseJson.getJSONObject("result");
                    log.info("data = " + data);
                } catch (Exception e) {
                    log.info("Failed to parse JSON: " + e.getMessage());
                }
            } else {
                log.info("No 'code' field in the response: " + response);
            }
        });
        return getResponse;
    }

至此,就可以完成发网络请求了!

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Kafka 消费者进程中使用 WebClient 发起网络请求,您可以使用 Spring Framework 中的 WebClient 库来完成。WebClient 是一种异步、非阻塞的 HTTP 客户端,可以与任何 HTTP 服务进行交互,并支持许多功能,例如基本身份验证、Cookie 管理和文件上传等。 以下是一些使用 Spring WebClient 发起网络请求的示例代码: 首先,您需要添加以下 Maven 依赖项: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> ``` 然后,您可以使用 WebClient 创建一个 GET 请求: ``` WebClient client = WebClient.create(); client.get() .uri("http://example.com") .retrieve() .bodyToMono(String.class) .subscribe(System.out::println); ``` 此代码将向 http://example.com 发送一个 GET 请求,并将响应主体转换为字符串。当收到响应时,它将在控制台上打印响应。 如果您需要向服务器发送 POST 请求并传递一些数据,您可以使用以下代码: ``` Mono<Void> result = WebClient.create() .post() .uri("http://example.com") .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue("{\"name\": \"John\", \"age\": 30}")) .retrieve() .bodyToMono(Void.class); result.block(); ``` 这个例子将使用 JSON 格式的数据向 http://example.com 发送一个 POST 请求。在这种情况下,我们使用了 BodyInserters.fromValue() 方法将数据转换为 JSON 格式,并将 Content-Type 头设置为 application/json。在这个例子中,我们不关心响应体,所以我们将响应体转换为 Void 类型。 需要注意的是,在 Kafka 消费者进程中使用 WebClient 发起网络请求可能会阻塞消费者线程,因此建议使用异步的方式来处理网络请求,以确保消费者线程的及时释放。 ### 回答2: 在Kafka消费者进程中使用WebClient发起网络请求可以通过以下步骤实现: 1. 引入相关依赖:首先,需要在项目的构建文件(如pom.xml或build.gradle)中添加对WebFlux和WebClient的依赖。例如,对于Maven项目,可以在pom.xml文件中添加以下依赖: ```xml <dependencies> <!-- 其他依赖项 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- 其他依赖项 --> </dependencies> ``` 2. 创建WebClient实例:在消费者进程的代码中,首先需要创建一个WebClient实例。可以使用WebClient.builder()方法来创建一个WebClient.Builder对象,并使用不同的配置方法来设置需要的特性,例如超时时间、连接池等。 ```java WebClient webClient = WebClient.builder() .baseUrl("http://example.com") // 设置请求的基本URL .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // 设置请求头 .build(); ``` 3. 发起网络请求:一旦WebClient实例创建好,就可以使用其提供的方法来发起网络请求。常用的方法包括get()、post()、put()、delete()等。根据具体需求,可以设置请求的URL、请求体、请求参数等信息,并通过调用exchange()或retrieve()方法来执行请求并获取响应。 ```java Mono<String> response = webClient.get() .uri("/api/endpoint") // 设置请求的相对URL .retrieve() // 发起请求并获取响应 .bodyToMono(String.class); // 将响应体解析为字符串 response.subscribe(res -> { // 处理响应结果 System.out.println(res); }, err -> { // 处理请求失败的情况 err.printStackTrace(); }); ``` 通过上述步骤,我们就可以在Kafka消费者进程中使用WebClient发起网络请求,并处理返回结果或错误。根据实际需求,还可以配置更多WebClient的特性,例如添加拦截器、设置代理等,以满足不同的业务需求。 ### 回答3: Kafka消费者进程可以通过使用WebClient类,实现通过发起网络请求来进行交互。 首先,我们需要在Kafka消费者的代码中引入WebClient类的相关依赖库。可以使用Maven或者Gradle将以下依赖添加到项目中: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> ``` 然后,在Kafka消费者进程中创建一个WebClient实例,用于发起网络请求。可以通过WebClient.builder()方法来创建实例,并设置相关的请求配置。例如: ```java WebClient webClient = WebClient.builder() .baseUrl("http://example.com") // 设置请求的基础URL .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // 设置请求头 .build(); ``` 接下来,可以使用WebClient实例来发起网络请求。例如,使用GET方法请求一个URL,并读取响应内容: ```java webClient.get() .uri("/api/getData") // 设置请求的URI .retrieve() // 发起请求并获取响应 .bodyToMono(String.class) // 将响应转换为字符串 .subscribe(response -> { System.out.println(response); // 打印响应内容 }); ``` 使用POST方法发送包含请求体的请求: ```java webClient.post() .uri("/api/submitData") // 设置请求的URI .bodyValue(requestData) // 设置请求体数据 .retrieve() // 发起请求并获取响应 .bodyToMono(String.class) // 将响应转换为字符串 .subscribe(response -> { System.out.println(response); // 打印响应内容 }); ``` 需要注意的是,WebClient是一种基于响应式编程的客户端工具,所以使用它时需要注意异步操作和订阅响应的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值