RestTemplate发送get、post请求(form、json)(功能封装) 20256259编辑

Heaven helps those who help themselves
资深码农+深耕理财=财富自由
欢迎关注

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

Created by Marydon on 2023-05-26 17:16

1.情景展示

一般情况下,如果要从服务器A去调服务器B,需要我们自己封装一个HttpUtils工具类。

发送GET或POST请求完成服务器对服务器的数据交互,使用RestTemplate组件就可以帮我们完成。

利用spring组件RestTemplate,如何用代码如何实现?

2.准备工作

<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
<optional>true</optional>
</dependency>
<!--spring-web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.18</version>
<optional>true</optional>
</dependency>

说明:

通过 RestTemplate,我们可以非常方便的进行 Rest API 调用。

但是,在 Spring 5 中已经不再建议使用 RestTemplate,而是建议使用 WebClient。WebClient 是一个支持异步调用的 Client。

3.解决方案

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
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.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
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;

GET请求封装

/**
* 利用Spring组件发送GET请求
* @description:
* get请求调用sendGet()
* post请求调用sendPost()
* @author: Marydon
* @date: 2023-05-26 9:21
* @version: 1.0
* @email: marydon20170307@163.com
*/
@Slf4j
public class SpringHttpUtils {
/**
* 发送get请求,拿到响应数据
* @param url 请求地址
* @param paramsMap 请求入参
* @param responseDataClass 响应数据类型所对应的Class
* @return T 响应数据
* 数据类型与入参responseDataClass保持一致
*/
public static <T> T sendGet(String url, Map<String, Object> paramsMap, Class<T> responseDataClass) {
// 存放参数名与参数值
List<NameValuePair> nameValuePairs = new ArrayList<>(paramsMap.size());
// 遍历取出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();
log.info(uri.toString());
} catch (URISyntaxException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
return getResponse(uri, responseDataClass);
}
/**
* 调接口并完成响应数据的格式转换
* @param uri
* @param responseDataClass
* 响应数据类型多对应的java类
* @return 接口返回的数据
*/
private static <T> T getResponse(URI uri, Class<T> responseDataClass) {
if (null == uri) {
throw new RuntimeException("请求地址URL为空!");
}
// 发送请求并获取响应结果
String responseData = invokeGet(uri);
// 响应数据类型
T responseDataType;
try {
responseDataType = responseDataClass.newInstance();
if (responseDataType instanceof JSONObject) {
return (T) JSON.parseObject(responseData);
} else if (responseDataType instanceof JSONArray) {
return (T) JSON.parseArray(responseData);
} else {
return (T) responseData;
}
} catch (InstantiationException | IllegalAccessException e ) {
e.printStackTrace();
return null;
}
}
/**
* 发送GET请求并获取响应结果
* @param uri
* 含:请求地址及请求参数
* @return 响应结果
* String
*/
private static String invokeGet(URI uri) {
//
RestTemplate restTemplate = getRestTemplate();
// 发送GET请求并拿到响应数据
final ResponseEntity<String> getEntity = restTemplate.getForEntity(uri, String.class);
// 响应数据
String resultData =getEntity.getBody();
log.info("接口地址:{}\n返回响应数据:\n{}", uri.toString(), resultData);
return resultData;
}
/**
* 创建Rest API 客户端
* @explain
* 其目的是:为了修改响应字符集
* @return
*/
private static RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> httpMessageConverters = restTemplate.getMessageConverters();
httpMessageConverters.forEach(httpMessageConverter -> {
if(httpMessageConverter instanceof StringHttpMessageConverter){
StringHttpMessageConverter messageConverter = (StringHttpMessageConverter) httpMessageConverter;
// 将响应字符集改成UTF-8,默认是ISO-8859-1
messageConverter.setDefaultCharset(StandardCharsets.UTF_8);
}
});
return restTemplate;
}
}

POST请求封装(FORM表单)

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.18</version>
<optional>true</optional>
</dependency>
import org.springframework.http.HttpEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
/**
* 发送post请求,拿到响应数据
* @description 提交form表单
* @param url 请求地址
* @param paramsMap 请求入参
* @param responseDataClass 响应数据类型所对应的Class
* @return T 响应数据
* 数据类型与入参responseDataClass保持一致
*/
public static <T> T sendPostByForm(String url, Map<String, Object> paramsMap, Class<T> responseDataClass) {
RestTemplate restTemplate = getRestTemplate();
// 请求参数必须放到MultiValueMap当中
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>(paramsMap.size());
paramMap.forEach(paramMap::add);
// 必须将MultiValueMap放到HttpEntity当中
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(paramMap);
final ResponseEntity<T> postEntity = restTemplate.postForEntity(url, httpEntity, responseDataClass);
// 响应数据
T body = postEntity.getBody();
log.info("接口地址:{}\n返回响应数据:\n{}", url, body);
return body;
}

POST请求封装(JSON)

/**
* 发送post请求,拿到响应数据
* @description JSON提交
* @param url 请求地址
* @param params 请求入参
* Map或JSON
* @param responseDataClass 响应数据类型所对应的Class
* @return T 响应数据
* 数据类型与入参responseDataClass保持一致
*/
public static <T> T sendPostByJson(String url, Object params, Class<T> responseDataClass) {
// JSONObject paramsJson;
String paramsJsonStr;
if (params instanceof JSONObject) {
paramsJsonStr = params.toString();
} else {
// Map转JSON
// paramsJson = MapUtils.toAliJson((Map<?, ?>) params);
paramsJsonStr = JSON.toJSONString(params);
}
HttpHeaders headers = new HttpHeaders();
// 相当于:application/json
headers.setContentType(MediaType.APPLICATION_JSON);
// 必须将MultiValueMap放到HttpEntity当中
HttpEntity<String> httpEntity = new HttpEntity<>(paramsJsonStr, headers);
RestTemplate restTemplate = getRestTemplate();
final ResponseEntity<T> postEntity = restTemplate.postForEntity(url, httpEntity, responseDataClass);
// 响应数据
T body = postEntity.getBody();
log.info("接口地址:{}\n返回响应数据:\n{}", url, body);
return body;
}

4.调用

GET请求测试

public static void main(String[] args) {
Map<String, Object> paramsMap = new HashMap<>(2);
paramsMap.put("Name", "Marydon");
paramsMap.put("Blog", "博客园");
// 实际返回的是text/html
sendGetRequest("http://www.cnblogs.com", paramsMap, String.class);
}

POST请求测试

form表单

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

JSON

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

 

写在最后

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

 相关推荐:

与君共勉:最实用的自律是攒钱,最养眼的自律是健身,最健康的自律是早睡,最改变气质的自律是看书,最好的自律是经济独立 。

您的一个点赞,一句留言,一次打赏,就是博主创作的动力源泉!

↓↓↓↓↓↓写的不错,对你有帮助?赏博主一口饭吧↓↓↓↓↓↓

posted @   Marydon  阅读(6259)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2018-05-26 excel 如何为列添加指定内容(字符串)
2018-05-26 win10 显示详细信息窗格
2017-05-26 java 八种基本数据类型之与对应的封装类之间的相互转化
2017-05-26 javascript-使用el表达式获取后台传递的数据
2017-05-26 java Map
2017-05-26 java List集合
点击右上角即可分享
微信分享提示
sorry,本博客所有代码禁止复制,原创代码需扫码支付方可获取!
关闭

1、先加好友再付费,点我加好友;

2、代码不能满足你的需求?加好友付费定制你的专属代码!

3、付费标准及方式,点我查看详情。