Spring RestTemplate調(diào)用外部接口怎樣實現(xiàn)無侵入日志打印

Spring Boot項目調(diào)用外部接口,大部分使用RestTemplate調(diào)用,本文主要解決RestTemplate調(diào)用第三方接口時怎么無侵入實現(xiàn)動態(tài)header增加和請求日志輸出
以下直接上代碼:

<hr/>
import com.google.common.base.Charsets;
import com.mycompany.projectname.common.constant.AppCons;
import com.mycompany.projectname.context.LoginInfoHolder;
import com.mycompany.projectname.util.ApigatewayUtil;
import mycompany.projectname.util.FastJsonUtils;
import mycompany.projectname.util.Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URI;
import java.net.URLDecoder;

/**
 * RestTempate請求攔截器
 * Created by author on 2018/11/17.
 */
@Slf4j
@Component
public class ApiLoggerInterceptor implements ClientHttpRequestInterceptor {
    private final String apiHost = "api.mycompay.com";
    private final String aServicePath = "/a-service/v1";
    private final String bServicePath = "/b-service/1.0";

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        traceRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);
        traceResponse(request, response);
        return response;
    }

    private void traceRequest(HttpRequest request, byte[] body) throws IOException {
        log.info("===========================request begin================================================");
        addCommonHeader(request);
        log.info("URI         :{} {}", request.getMethod(), URLDecoder.decode(request.getURI().toString(), Charsets.UTF_8.name()));
        log.info("Headers     : {}", request.getHeaders());
        log.info("Request body: {}", new String(body, Charsets.UTF_8));
        log.info("===========================request end==================================================");
    }

    private void addCommonHeader(HttpRequest request) {
        URI uri = request.getURI();
        HttpHeaders headers = request.getHeaders();
        if(uri.getHost().indexOf(apiHost) > -1) {//apigateway調(diào)用,需要簽名信息
            headers.setAll(ApigatewayUtil.generateApiGatewayHeader(uri));
        }
        if(uri.getPath().startsWith(aServicePath)) {//組裝a service特殊要求的header
            headers.add("appCode", System.getProperty("appCode"));
            headers.add("appSecret", System.getProperty("appSecret"));
        } else if(uri.getPath().startsWith(aServicePath)) {//b service需要的特殊header
            headers.add("X-TENANT", LoginInfoHolder.tenantId());
        }
    }

    private void traceResponse(HttpRequest request, ClientHttpResponse response) throws IOException {
        String respContent = Utils.readInputStream(response.getBody());
        log.info("============================response begin==========================================");
        log.info("Response Status : {} {}", response.getStatusCode(), response.getStatusText());
        log.info("Headers         : {}", response.getHeaders());
        if(request.getURI().getPath().startsWith("/c-service/1.0/dblist/")) {
            respContent = FastJsonUtils.toJsonString(FastJsonUtils.parse(respContent), (object, name, value) -> {
                if (name.equalsIgnoreCase("dbPassword")) {
                    //false表示指定字段將被排除在外
                    return false;
                }
                return true;
            });
        }
        log.info("Response body   : {}{}", StringUtils.substring(respContent,0, AppCons.LENGTH_OF_API_LOG),
                respContent.length() > AppCons.LENGTH_OF_API_LOG ? "...略" : "");
        log.info("=======================response end=================================================");
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。