首页 > 其他分享 >WebClient发送get、post请求(form、json)(功能封装)

WebClient发送get、post请求(form、json)(功能封装)

时间:2023-05-30 19:11:05浏览次数:57  
标签:请求 form get url paramsMap json org import WebClient

1.情景展示

Spring3.0引入了RestTemplate,但是在后来的官方源码中介绍,RestTemplate有可能在未来的版本中被弃用,所谓替代RestTemplate,在Spring5中引入了WebClient作为非阻塞式Reactive Http客户端。

WebClient处理单个HTTP请求的响应时长并不比RestTemplate更快,但是它处理并发的能力更强。

所以响应式非阻塞IO模型的核心意义在于:提高了单位时间内有限资源下的服务请求的并发处理能力,而不是缩短了单个服务请求的响应时长。

如何使用spring组件WebClient发送Http请求?

2.准备工作

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>2.6.6</version>
    <optional>true</optional>
</dependency>

3.解决方案

3.1 GET请求封装

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.18</version>
    <optional>true</optional>
</dependency>
import code.marydon.encapsulation.dataType.MapUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.http.HttpMethod;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 利用spring组件WebClient发送http请求(GET、POST)
 * @description: 目前只实现了同步请求,由于没有异步请求实现场景,所以并未封装,网上一搜就有。
 * @author: Marydon
 * @date: 2023-05-30 16:28
 * @version: 1.0
 * @email: [email protected]
 */
@Slf4j
public class WebClientUtils {

    /**
     * WebClient发送GET请求
     * @description 同步请求
     * @param url 请求地址
     * @param paramsMap 请求参数
     * @param responseClass 响应数据的数据类型
     * @return 响应数据
     */
    public static <T> T sendGet(String url, Map<String, String> paramsMap, Class<T> responseClass) {
        List<NameValuePair> nameValuePairs = new ArrayList<>(paramsMap.size());
        if (!MapUtils.isEmpty(paramsMap)) {
            // 存放参数名与参数值
            // 遍历取出key和value并将其作为参数的name和value
            paramsMap.forEach((k, v) -> nameValuePairs.add(new BasicNameValuePair(k, v)));
        }

        URI uri;
        try {
            // 形如:
            // http://www.cnblogs.com?Blog=%E5%8D%9A%E5%AE%A2%E5%9B%AD&Name=Marydon
            uri = new URIBuilder(url)
                    // 设置URL的字符集
                    .setCharset(StandardCharsets.UTF_8)
                    // 参数会被拼接到URL后面,中文会被自动编码,特殊字符也会被编码
                    // url?param1=value1&param2=value2
                    .addParameters(nameValuePairs)
                    .build();
        } catch (URISyntaxException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }

        Mono<T> mono = WebClient
                // 创建WenClient实例
                .create()
                // 请求方式
                .method(HttpMethod.GET)
                // 请求url
                .uri(uri)
                // 获取响应结果
                .retrieve()
                // 将结果转换为指定类型
                .bodyToMono(responseClass);
        // block方法返回最终调用结果,block方法是阻塞的(同步请求,不调用block方法,可以改成异步请求)
        T responseData = mono.block();
        log.info("请求地址:{}\n响应数据:{}", uri, responseData);

        return responseData;
    }
}

测试

public static void main(String[] args) {
    Map<String, Object> paramsMap = new HashMap<>(2);
    paramsMap.put("Name", "Marydon");
    paramsMap.put("Blog", "博客园");

    sendGet("https://www.cnblogs.com", paramsMap, String.class);

}

结果

从上图我们可以看到:发送的是GET请求,并且是问号传参。 

3.2 POST请求封装(FORM表单)

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.18</version>
    <optional>true</optional>
</dependency>
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
/**
 * 发送POST请求(form表单)
 * @description 同步请求
 * @param url
 * @param map
 * @param responseDataClass
 * @return 响应数据
 */
public static <T> T sendPostByForm(String url, Map<String, Object> map, Class<T> responseDataClass) {
    // 请求参数必须放到MultiValueMap当中
    MultiValueMap<String, Object> paramsMap = new LinkedMultiValueMap<>(map.size());
    // 把Map中的数据复制到MultiValueMap当中
    map.forEach(paramsMap::add);

    // 当传递的请求体对象是一个MultiValueMap对象时,WebClient默认发起的是Form提交,即:application/x-www-form-urlencoded
    Mono<T> mono = WebClient
            // 创建WenClient实例
            .create()
            // 请求方式
            .method(HttpMethod.POST)
            // 请求url
            .uri(url)
            // 请求参数
            .bodyValue(paramsMap)
            // 获取响应结果
            .retrieve()
            // 将结果转换为指定类型
            .bodyToMono(responseDataClass);

    // block方法返回最终调用结果,block方法是阻塞的
    T responseData = mono.block();
    log.info("请求地址:{}\n请求参数:{}\n响应数据:{}", url, paramsMap, responseData);

    return responseData;
}

测试代码

Map<String, Object> paramsMap = new HashMap<>(2);
paramsMap.put("Name", "Marydon");
paramsMap.put("Blog", "博客园");

sendPostByForm("https://www.cnblogs.com", paramsMap, String.class);

下面这句话证明,我们发送的确确实实是FORM表单请求

测试结果

3.3 POST请求封装(JSON请求)

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.18</version>
    <optional>true</optional>
</dependency>
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

JSON的本质,还是字符串。

所以,我们在发送请求时,并不是要传递JSON对象,而是传json字符串就可以啦。

/**
 * 发送post请求(JSON数据)
 * @description 同步请求
 * @param url
 * @param params 请求入参
 *      Map或JSON
 * @param responseDataClass
 * @return 响应数据
 */
public static <T> T sendPostByJson(String url, Object params, Class<T> responseDataClass) {

    String paramsJsonStr;
    if (params instanceof JSONObject) {
        paramsJsonStr = params.toString();
    } else {
        // Map转JSON
        paramsJsonStr = JSON.toJSONString(params);
    }

    Mono<T> mono = WebClient
            // 创建WenClient实例
            .builder()
            // 设置请求内容类型为:Content-Type=application/json
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .build()
            // 请求方式
            .method(HttpMethod.POST)
            // 请求url
            .uri(url)
            // 请求参数
            .bodyValue(paramsJsonStr)
            // 获取响应结果
            .retrieve()
            // 将结果转换为指定类型
            .bodyToMono(responseDataClass);

    // block方法返回最终调用结果,block方法是阻塞的(同步请求)
    T responseData = mono.block();
    log.info("请求地址:{}\n请求参数:{}\n响应数据:{}", url, paramsJsonStr, responseData);

    return responseData;
}

调用

sendPostByJson("https://www.cnblogs.com", paramsMap, String.class);

从下面这句输出,可以看出:发送的是JSON字符串

结果

 

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐:

标签:请求,form,get,url,paramsMap,json,org,import,WebClient
From: https://www.cnblogs.com/Marydon20170307/p/17444133.html

相关文章

  • JSON-RPC示例代码(Java实现)
    以下是一个使用Java实现的JSON-RPC示例代码。该示例使用了JSON-RPC2.0规范和Jackson库进行序列化和反序列化。在这个示例中,我们将创建一个服务器和一个客户端,演示如何进行远程过程调用。首先,确保您已经安装了Java开发环境(JDK)和Maven构建工具。接下来,我们将创建一个Maven项目,并......
  • Python 读取图片 转 base64 并生成 JSON
    Python读取图片转base64并生成JSONimportjsonimportbase64img_path=r'D:\OpenSource\PaddlePaddle\PaddleOCR\images\005.jpeg';withopen(img_path,'rb')asfile:image_data1=file.read()image=base64.b64encode(image_data1).de......
  • flutter开发Nuget.exe not found, trying to download or use cached version解决方法
    问题:Nuget.exenotfound,tryingtodownloadorusecachedversion解决方法:首先确保VisualStudio安装,这个是flutter构建Window应用必须的,并且安装了对应的WindowsSDK,通过VisualStudioInstaller安装管理员身份运行cmd窗口,然后执行wingetinstallMicrosoft.NuGet安装NuG......
  • 【Python】将中文字符写入json文件
    ensure_asciiimportjsondict1={'name':'时间','data':['2023-04-1305:00']},{'name':'雨量mm/h','data':['0.0000']},{'name':'温度℃','data':[&......
  • 轻松解析JSON数据,欢迎使用Jsoneasy.com!
    大家好!今天我来向大家推荐一个强大而便捷的JSON数据解析工具——Jsoneasy.com。如果你经常处理JSON数据,无论是开发人员、数据分析师还是任何对JSON数据处理感兴趣的人,Jsoneasy.com将会成为你的得力助手。Jsoneasy.com是一个专注于JSON数据解析和处理的在线工具。它提供了简单易用......
  • The Importance of Particle Size Analysis in Preformulation Studies
    Thesizeoftheparticlesiscalledparticlesize.TheparticlesizeoftheAPIiscloselyrelatedtothehomogeneityofthepreparationprocessintermsofmixing,theaccuracyofdosage,andcompressibility,andithasanimpactonthesolubility,durat......
  • ElementUI的form表单验证注意事项
    ElementUI的form表单验证注意事项1.踩过的坑,记录一下。验证表单时一直提示必填项未填写,实际已经填写了。2.el-form的正确使用流程el-form就是最外层的form表单,做验证有三个必填属性,不填写验证就会不正确。ref属性:相当于ID,稍后的提交按钮函数会用到它。:model:绑定要用......
  • [NextJS] getStaticProps
    Continue... Ref: Next.js产品级的React框架-中文开发入门教学-编写静态页面属性getStaticProps  为了爬虫,所以这么写。importHeadfrom'next/head'exportdefaultfunctionHome(props){const{datalist}=props;return(<div>......
  • Nuget使用教程
    视频链接:.NET6教程,.NetCore2022视频教程,杨中科主讲_哔哩哔哩_bilibiliNeGet了解NuGet以前的手工下载dll:不好找;版本不好匹配;依赖复杂;趋势Linux:apt、yumJavascript:npmJava:Maven、GradlePvthon:pip官网地址:https://www.nuget.org(1)精确搜索(Zack.EFCore.Batch......
  • form表单特性总结
    1.form属性<formid="user_form"method="get"></form><div>年龄:<inputname="age"form="user_form"></></div>外部元素可以与非父级表单关联表单提交,可以携带表单外部元素的值2.提交按钮的form相关属性包括formaction:覆盖fo......