目录
虽然spring已经帮我们简化了http的请求,但是在实际应用中,我们还是需要写很多重复的代码,显得不够优雅,所以我们还需要对RestTemplate再做一层封装,使外层的调用能够更加的规范和简单。
一、封装思路
我们需要构建一个基类,这个基类封装全部底层基础的请求方法,如GET/POST。
/**
* 封装一些常用的远程调用方法
*
*/
public class BackendHttpRequest {
//伪代码
get请求方法
post的json格式请求方法
post的x-www-form-urlencoded格式请求方法
....
}
将需要远程调用的方法封装在一个service服务类,同时继承上面的基类,这个服务类内部即可调用基类的请求方法。
@Service
class AServiceImpl extends BackendHttpRequest implements AService {
//获取天气数据api
public String getWeatherData(WeatherDataRequestBean params){
//伪代码
//调用基类的getData方法,传入请求api接口地址,并带上参数params
//params内有city城市字段,根据城市名称查询当地天气
String resBody = this.getData(apiUrl, params);
return resBody;
}
}
这样,我们就大概构建了一套请求的规范模型,并使用fastjson序列化传入的bean,下面会具体详细说明实战中如何应用。
二、GET方式
以下具体说明如何调用微信的”公众号的全局唯一接口调用凭据”接口,接口文档
/**
* get请求
*
* @param api 请求url
* @param reqObj 请求request实体
* @return
*/
public String getData(String api, Object reqObj) {
return this.getData(api, reqObj, null);
}
/**
* get请求
*
* @param api 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String getData(String api, Object reqObj, Map<String, String> addHeaders) {
JSONObject params = null;
if (reqObj instanceof JSONObject) {
params = (JSONObject) reqObj;
} else {
params = JSONObject.parseObject(JSON.toJSONString(reqObj));
}
//将map转换为query参数
String queryParams = HttpUtil.toParams(params, Charset.forName("UTF-8"));
String requestUrl = api + "?" + queryParams;
HttpEntity<String> entity = this.getMethodHttpEntity(addHeaders);
ResponseEntity<String> responseEntity = restTemplate.exchange(URI.create(requestUrl), HttpMethod.GET, entity, String.class);
return responseEntity.getBody();
}
同时构建一些公共的方法。
/**
* 获取get方法的HttpEntity
*
* @param addHeaders 添加的头部
* @return
*/
public HttpEntity<String> getMethodHttpEntity(Map<String, String> addHeaders) {
HttpHeaders headers = this.getJsonDataHttpHeaders();
this.addHeaders(headers, addHeaders);
HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
return requestEntity;
}
/**
* 获取json请求头
*
* @return
*/
public HttpHeaders getJsonDataHttpHeaders() {
HttpHeaders headers = this.getHttpHeaders(MediaType.APPLICATION_JSON);
return headers;
}
/**
* 获取指定mediaType请求头
*
* @param mediaType
* @return
*/
public HttpHeaders getHttpHeaders(MediaType mediaType) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(mediaType);
return headers;
}
GET方式的封装,重载了两个方法,其中一个方法可以传入自定义的头部参数。
对于请求的参数,统一转变成JSON对象,再使用hutool的工具类HttpUtil,将其转变为query参数形式,即key=value&key=value,最后拼接在url上。
最后,我们使用的是restTemplate.exchange方法,而没有使用getForEntity,是因为之前这里有踩过坑。
@Service
public class TokenServiceImpl extends BackendHttpRequest implements TokenService {
@Override
public AccessTokenResponse accessToken(AccessTokenRequest accessTokenRequest) {
String apiUrl = "https://api.weixin.qq.com/cgi-bin/token";
String resText = this.getData(apiUrl, accessTokenRequest);
if (StrUtil.isNotBlank(resText)) {
AccessTokenResponse response = JSON.parseObject(resText, AccessTokenResponse.class);
return response;
}
return null;
}
}
请求实体
@Data
public class AccessTokenRequest {
@JSONField(name = "appid")
private String appId;
@JSONField(name = "secret")
private String appSecret;
@JSONField(name = "grant_type")
private String grantType;
}
响应实体
@Data
public class AccessTokenResponse {
@JSONField(name = "errcode")
private String errcode;
@JSONField(name = "errmsg")
private String errmsg;
@JSONField(name = "access_token")
private String accessToken;
@JSONField(name = "expires_in")
private Integer expiresIn;
}
三、POST方式
主要对form-data、x-www-form-urlencoded、json等格式分别进行处理。
form-data
/**
* form-data的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @return
*/
public String postFormData(String requestUrl, Object reqObj) {
return this.postFormData(requestUrl, reqObj, null);
}
/**
* form-data的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String postFormData(String requestUrl, Object reqObj, Map<String, String> addHeaders) {
HttpEntity<MultiValueMap<String, Object>> entity = this.getFormRequestHttpEntity(reqObj, MediaType.MULTIPART_FORM_DATA_VALUE, addHeaders);
String resText = restTemplate.postForObject(requestUrl, entity, String.class);
return resText;
}
请求体需要使用MultiValueMap进行封装,构建公共方法将请求bean转换为MultiValueMap。
/**
* 请求request实体转form-data的map
*
* @param reqObj 请求request实体
* @return
*/
public MultiValueMap<String, Object> requestBeanToFormParams(Object reqObj) {
Map<String, Object> params = JSONObject.parseObject(JSON.toJSONString(reqObj), HashMap.class);
MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
for (String key : params.keySet()) {
multiValueMap.add(key, params.get(key));
}
return multiValueMap;
}
x-www-form-urlencoded
/**
* x-www-form-urlencoded的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @return
*/
public String postFormUrlencoded(String requestUrl, Object reqObj) {
return this.postFormUrlencoded(requestUrl, reqObj, null);
}
/**
* x-www-form-urlencoded的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String postFormUrlencoded(String requestUrl, Object reqObj, Map<String, String> addHeaders) {
HttpEntity<MultiValueMap<String, Object>> entity = this.getFormRequestHttpEntity(reqObj, MediaType.APPLICATION_FORM_URLENCODED_VALUE, addHeaders);
String resText = restTemplate.postForObject(requestUrl, entity, String.class);
return resText;
}
方式跟form-data相同,只是header的content-type不相同。
/**
* 获取x-www-form-urlencoded请求头
*
* @return
*/
public HttpHeaders getFormUrlencodedHttpHeaders() {
HttpHeaders headers = this.getHttpHeaders(MediaType.APPLICATION_FORM_URLENCODED);
return headers;
}
/**
* 获取form-data请求头
*
* @return
*/
public HttpHeaders getFormDataHttpHeaders() {
HttpHeaders headers = this.getHttpHeaders(MediaType.MULTIPART_FORM_DATA);
return headers;
}
json
/**
* json的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @return
*/
public String postJsonData(String requestUrl, Object reqObj) {
return this.postJsonData(requestUrl, reqObj, null);
}
/**
* json的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String postJsonData(String requestUrl, Object reqObj, Map<String, String> addHeaders) {
HttpEntity<String> entity = this.getJsonRequestHttpEntity(reqObj, addHeaders);
String resText = restTemplate.postForObject(requestUrl, entity, String.class);
return resText;
}
json格式的请求只需要将请求体转化为json字符串即可。
/**
* 获取json请求的HttpEntity
*
* @param obj 请求request实体
* @param addHeaders 添加的头部
* @return
*/
public HttpEntity<String> getJsonRequestHttpEntity(Object obj, Map<String, String> addHeaders) {
HttpHeaders headers = this.getJsonDataHttpHeaders();
this.addHeaders(headers, addHeaders);
JSONObject params = null;
if (obj instanceof JSONObject) {
params = (JSONObject) obj;
} else {
params = JSONObject.parseObject(JSON.toJSONString(obj));
}
HttpEntity<String> entity = new HttpEntity<>(params.toString(), headers);
return entity;
}
四、Header处理
在请求头的处理中,可以针对jwt进行处理。
/**
* 添加自定义的头部
*
* @param headers
* @param addHeaders
*/
public void addHeaders(HttpHeaders headers, Map<String, String> addHeaders) {
if (addHeaders != null) {
for (String key : addHeaders.keySet()) {
if ("Bearer-Auth".equals(key)) {//jwt授权
headers.setBearerAuth(addHeaders.get(key));
continue;
}
headers.set(key, addHeaders.get(key));
}
}
}
我们还可以做一些公共的加密鉴权的方法在这里,这样就不需要每个请求方法都写一遍加密方式。
五、完整代码
public class BackendHttpRequest {
@Resource
RestTemplate restTemplate;
/**
* get请求
*
* @param api 请求url
* @param reqObj 请求request实体
* @return
*/
public String getData(String api, Object reqObj) {
return this.getData(api, reqObj, null);
}
/**
* get请求
*
* @param api 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String getData(String api, Object reqObj, Map<String, String> addHeaders) {
JSONObject params = null;
if (reqObj instanceof JSONObject) {
params = (JSONObject) reqObj;
} else {
params = JSONObject.parseObject(JSON.toJSONString(reqObj));
}
//将map转换为query参数
String queryParams = HttpUtil.toParams(params, Charset.forName("UTF-8"));
String requestUrl = api + "?" + queryParams;
HttpEntity<String> entity = this.getMethodHttpEntity(addHeaders);
ResponseEntity<String> responseEntity = restTemplate.exchange(URI.create(requestUrl), HttpMethod.GET, entity, String.class);
return responseEntity.getBody();
}
/**
* form-data的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @return
*/
public String postFormData(String requestUrl, Object reqObj) {
return this.postFormData(requestUrl, reqObj, null);
}
/**
* form-data的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String postFormData(String requestUrl, Object reqObj, Map<String, String> addHeaders) {
HttpEntity<MultiValueMap<String, Object>> entity = this.getFormRequestHttpEntity(reqObj, MediaType.MULTIPART_FORM_DATA_VALUE, addHeaders);
String resText = restTemplate.postForObject(requestUrl, entity, String.class);
return resText;
}
/**
* x-www-form-urlencoded的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @return
*/
public String postFormUrlencoded(String requestUrl, Object reqObj) {
return this.postFormUrlencoded(requestUrl, reqObj, null);
}
/**
* x-www-form-urlencoded的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String postFormUrlencoded(String requestUrl, Object reqObj, Map<String, String> addHeaders) {
HttpEntity<MultiValueMap<String, Object>> entity = this.getFormRequestHttpEntity(reqObj, MediaType.APPLICATION_FORM_URLENCODED_VALUE, addHeaders);
String resText = restTemplate.postForObject(requestUrl, entity, String.class);
return resText;
}
/**
* json的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @return
*/
public String postJsonData(String requestUrl, Object reqObj) {
return this.postJsonData(requestUrl, reqObj, null);
}
/**
* json的post请求
*
* @param requestUrl 请求url
* @param reqObj 请求request实体
* @param addHeaders 添加的头部 如需要使用jwt,key名称需设为"Bearer-Auth"
* @return
*/
public String postJsonData(String requestUrl, Object reqObj, Map<String, String> addHeaders) {
HttpEntity<String> entity = this.getJsonRequestHttpEntity(reqObj, addHeaders);
String resText = restTemplate.postForObject(requestUrl, entity, String.class);
return resText;
}
/**
* 请求request实体转form-data的map
*
* @param reqObj 请求request实体
* @return
*/
public MultiValueMap<String, Object> requestBeanToFormParams(Object reqObj) {
Map<String, Object> params = JSONObject.parseObject(JSON.toJSONString(reqObj), HashMap.class);
MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
for (String key : params.keySet()) {
multiValueMap.add(key, params.get(key));
}
return multiValueMap;
}
/**
* 获取get方法的HttpEntity
*
* @param addHeaders 添加的头部
* @return
*/
public HttpEntity<String> getMethodHttpEntity(Map<String, String> addHeaders) {
HttpHeaders headers = this.getJsonDataHttpHeaders();
this.addHeaders(headers, addHeaders);
HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
return requestEntity;
}
/**
* 获取form请求的HttpEntity
*
* @param reqObj 请求request实体
* @param contentType form请求类型
* @param addHeaders 添加的头部
* @return
*/
public HttpEntity<MultiValueMap<String, Object>> getFormRequestHttpEntity(Object reqObj, String contentType, Map<String, String> addHeaders) {
HttpHeaders headers = null;
if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equals(contentType)) {
headers = this.getFormUrlencodedHttpHeaders();
} else if (MediaType.MULTIPART_FORM_DATA_VALUE.equals(contentType)) {
headers = this.getFormDataHttpHeaders();
}
this.addHeaders(headers, addHeaders);
MultiValueMap<String, Object> multiValueMap = this.requestBeanToFormParams(reqObj);
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(multiValueMap, headers);
return entity;
}
/**
* 获取json请求的HttpEntity
*
* @param obj 请求request实体
* @param addHeaders 添加的头部
* @return
*/
public HttpEntity<String> getJsonRequestHttpEntity(Object obj, Map<String, String> addHeaders) {
HttpHeaders headers = this.getJsonDataHttpHeaders();
this.addHeaders(headers, addHeaders);
JSONObject params = null;
if (obj instanceof JSONObject) {
params = (JSONObject) obj;
} else {
params = JSONObject.parseObject(JSON.toJSONString(obj));
}
HttpEntity<String> entity = new HttpEntity<>(params.toString(), headers);
return entity;
}
/**
* 获取x-www-form-urlencoded请求头
*
* @return
*/
public HttpHeaders getFormUrlencodedHttpHeaders() {
HttpHeaders headers = this.getHttpHeaders(MediaType.APPLICATION_FORM_URLENCODED);
return headers;
}
/**
* 获取form-data请求头
*
* @return
*/
public HttpHeaders getFormDataHttpHeaders() {
HttpHeaders headers = this.getHttpHeaders(MediaType.MULTIPART_FORM_DATA);
return headers;
}
/**
* 获取json请求头
*
* @return
*/
public HttpHeaders getJsonDataHttpHeaders() {
HttpHeaders headers = this.getHttpHeaders(MediaType.APPLICATION_JSON);
return headers;
}
/**
* 获取指定mediaType请求头
*
* @param mediaType
* @return
*/
public HttpHeaders getHttpHeaders(MediaType mediaType) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(mediaType);
return headers;
}
/**
* 添加自定义的头部
*
* @param headers
* @param addHeaders
*/
public void addHeaders(HttpHeaders headers, Map<String, String> addHeaders) {
if (addHeaders != null) {
for (String key : addHeaders.keySet()) {
if ("Bearer-Auth".equals(key)) {//jwt授权
headers.setBearerAuth(addHeaders.get(key));
continue;
}
headers.set(key, addHeaders.get(key));
}
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/93603.html