[springboot advanced] RestTemplate advanced packaging commonly used request methods

Table of contents

1. Packaging ideas

2. GET method

3. POST method

form-data

x-www-form-urlencoded

json

Four, Header processing

Five, complete code


Although spring has helped us simplify http requests, in practical applications, we still need to write a lot of repetitive code, which is not elegant enough, so we need to make another layer of encapsulation for RestTemplate, so that the outer layer calls can be more Standardized and simple.

1. Packaging ideas

We need to build a base class that encapsulates all underlying basic request methods, such as GET/POST.

/**
 * 封装一些常用的远程调用方法
 *
 */
public class BackendHttpRequest {

    //伪代码
    get请求方法

    post的json格式请求方法

    post的x-www-form-urlencoded格式请求方法

    ....

}

Encapsulate the method that needs to be called remotely in a service service class, and inherit the above base class at the same time, the request method of the base class can be called inside the service class.

@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;
    }
    
}

In this way, we roughly build a set of specification models for requests, and use fastjson to serialize the incoming beans. The following will detail how to apply them in actual combat.

2. GET method

The following describes how to call WeChat's "Global Unique Interface Call Credentials for Official Accounts" interface, interface documentation

    /**
     * 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();
    }

At the same time build some public methods. 

    /**
     * 获取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;
    }

The encapsulation of the GET method overloads two methods, one of which can pass in custom header parameters.

For the parameters of the request, it is uniformly converted into a JSON object, and then the tool class HttpUtil of hutool is used to convert it into a query parameter form, that is, key=value&key=value, and finally spliced ​​​​on the url.

In the end, we used the restTemplate.exchange method instead of getForEntity because there were pitfalls here before.

@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;
    }

}

requesting entity

@Data
public class AccessTokenRequest {

    @JSONField(name = "appid")
    private String appId;
    @JSONField(name = "secret")
    private String appSecret;
    @JSONField(name = "grant_type")
    private String grantType;
}

response entity

@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;
}

3. POST method

It mainly processes form-data, x-www-form-urlencoded, json and other formats respectively.

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;
    }

The request body needs to be encapsulated with MultiValueMap, and a public method is constructed to convert the request bean into a 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;
    }

The method is the same as form-data, except that the content-type of the header is different.

    /**
     * 获取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;
    }

A request in json format only needs to convert the request body into a json string.

    /**
     * 获取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;
    }

Four, Header processing

In the processing of the request header, it can be processed for 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));
            }

        }
    }

We can also make some public encryption and authentication methods here, so that there is no need to write the encryption method for each request method.

Five, complete code

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));
            }

        }
    }

}

Guess you like

Origin blog.csdn.net/lrb0677/article/details/125530522