springboot使用restTemplate调用第三方接口并打印请求日志实践

1.集成

1.1添加web依赖

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.6.5</version>
</dependency>

1.2在项目中注入restTemplate

package com.xxx.xxx;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate getTempLate() {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

2.工具类RequestUtil

package com.xxx.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class RequestUtil {

    @Resource
    private RestTemplate restTemplate;

    /**
     * 带请求头的GET请求调用方式
     *
     * @param url 请求URL
     * @param mapHeaders 请求头参数-map格式
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public <T> ResponseEntity<T> get(String url, Map<String, String> mapHeaders, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(mapHeaders);
        HttpEntity<?> requestEntity = new HttpEntity<>(httpHeaders);
        return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
    }


    /**
     * 带请求头的GET请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
    }

    // ----------------------------------POST-------------------------------------------------------

    /**
     * 带请求头的POST请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return post(url, httpHeaders, requestBody, responseType, uriVariables);
    }
    /**
     * 带请求头的POST请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return post(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 自定义请求头和请求体的POST请求调用方式
     *
     * @param url 请求URL
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
        return exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
    }


    // ----------------------------------通用方法-------------------------------------------------------

    /**
     * 记录请求和响应日志的通用方法
     */
    private <T> void logRequestAndResponse(String url, HttpMethod method, Object requestBody, 
            Map<String, String> headers, ResponseEntity<T> response, Map<String, ?> uriVariables) {
        StringBuilder logMsg = new StringBuilder("\n");
        // 记录请求信息
        logMsg.append("======================HTTP Request Begin======================\n");
        logMsg.append("Request URL: ").append(url).append("\n");
        logMsg.append("Request Method: ").append(method).append("\n");
        
        // 记录请求头
        if (headers != null && !headers.isEmpty()) {
            logMsg.append("Request Headers: ").append(JsonUtil.toString(headers)).append("\n");
        }

        // 记录请求param
        if (uriVariables != null && !uriVariables.isEmpty()) {
            logMsg.append("Request Params: ").append(JsonUtil.toString(uriVariables)).append("\n");
        }
        
        // 记录请求体
        if (requestBody != null) {
            logMsg.append("Request Body: ").append(JsonUtil.toString(requestBody)).append("\n");
        }
        
        // 记录响应信息
        logMsg.append("Response Status: ").append(response.getStatusCode()).append("\n");
        
        // 记录响应体,但跳过二进制内容
        if (response.getBody() != null) {
            if (response.getBody() instanceof byte[]) {
                logMsg.append("Response Body: [Binary Content]\n");
            } else {
                logMsg.append("Response Body: ").append(JsonUtil.toString(response.getBody())).append("\n");
            }
        }
        
        logMsg.append("======================HTTP Request End======================");
        log.info(logMsg.toString());
    }

    /**
     * 通用调用方式
     *
     * @param url 请求URL
     * @param method 请求方法类型
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
        ResponseEntity<T> response = restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
        // 记录日志
        Map<String, String> headers = new HashMap<>();
        if (requestEntity != null && requestEntity.getHeaders() != null) {
            requestEntity.getHeaders().forEach((key, value) -> 
                headers.put(key, String.join(",", value)));
        }
        logRequestAndResponse(url, method, requestEntity != null ? requestEntity.getBody() : null, headers, response, uriVariables);
        return response;
    }

}

注意:logRequestAndResponse为请求日志打印方法,即当你使用此工具类调用第三方接口时,会自动打印请求日志,包括:请求header、请求params、请求body、响应body等,且当响应体为字节流时不打印具体内容,避免输出乱码,效果如下图:

请求日志打印

3.调用接口实践

       try {
            ResponseEntity<xxxThirdReturn> response = requestUtil.post(url, headers, null, xxxReturn.class, params);
            // 处理响应
            if (response.getStatusCode().is2xxSuccessful()) {
                XXXReturn xxxReturn = response.getBody();
                if (xxxReturn.getResult().equals("01")) {
                    log.info("xxx接口-请求成功,响应结果为:{}", JsonUtil.toString(xxxThirdReturn));
                } else {
                    log.error("xxx接口-请求失败,响应结果为:{}", JsonUtil.toString(xxxReturn));
                }
            } else {
                log.error("xxx接口-请求失败,code码为:{}", response.getStatusCodeValue());
            }
        } catch (Exception e) {
            log.error("xxx接口-请求失败", e);
        }

完结撒花✿✿ヽ(°▽°)ノ✿

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值