同福

Java里使用WebClient模拟用户的 HTTP请求【20210508】

介绍

介绍

福哥需要在Java里面去请求其他服务器的接口,找了半天决定使用WebClient这个对象来实现。

GET

模拟用户的GET请求操作,这里面最CD的是拼凑GET请求的QueryString的问题。

如果你直接通过字符串拼接的方式把QueryString组织好拼到url后面,那么你就会发现如果QueryString的参数的值包含“?”、“&”、“=”这样的特殊字符的话,服务器端收到的QueryString就会乱套了。

如果你将QueryString里面的参数的值使用UrlEncode编码之后再拼接到url后面,那么你就会发现服务器端收到的QueryString是经过UrlEncode编码过的。

终极解决方案,看福哥的代码

String resp;
Mono<String> monoResp;
WebClient webClient;
String queryString;

webClient = WebClient.create();
queryString = "";
for(Map.Entry<String, String> entry : params.entrySet()){
    queryString += "&"+entry.getKey()+"={"+ entry.getKey() +"}";
}
if(!url.contains("?")){
    url += "?"+queryString.substring(1);
}
else{
    url += queryString;
}
monoResp = webClient.get()
        .uri(url, params)
        .retrieve()
        .bodyToMono(String.class);
resp = monoResp.block();

return resp;

POST

模拟用户的POST请求操作,这里面最大的问题还是传递参数的问题。

经过福哥的各种踩坑之后,得到了终极解决方案,就是使用BodyInserters.fromFormData将MultiValueMap转换后传递给body方法。

String resp;
Mono<String> monoResp;
WebClient webClient;
MultiValueMap<String, String> myParams = new LinkedMultiValueMap<>();

webClient = WebClient.create();
for(Map.Entry<String, String> entry : params.entrySet()){
    myParams.add(entry.getKey(), entry.getValue());
}
monoResp = webClient.post()
        .uri(url)
        .body(BodyInserters.fromFormData(myParams))
        .retrieve()
        .bodyToMono(String.class);
resp = monoResp.block();

return resp;

使用

我们建立一个测试控制器,写下如下代码,分别测试通过GET方式和POST方式请求接口的效果。

@RequestMapping("/net.tongfu.tfjava.test.httpclient")
public String responseTestHttpClient(

) {
    TFHttpClient httpClient = new TFHttpClient();

    Map<String, String> params = new HashMap<>();
    params.put("title", "福哥辛苦了!");
    params.put("content", "福哥加油哦~~");
    String a = httpClient.Get("http://192.168.1.113:8070/TFRouteMap.php", params);
    String b = httpClient.Post("http://192.168.1.113:8070/TFRouteMap.php", params);

    return "httpClient.Get:\n"+a+"\nhttpClient.Post:\n"+b;
}

df7a02c520092d9f.jpg

总结

使用WebClient对象可以轻松完成HTTP的GET请求或者POST请求。