我经历的几个公司,几乎都有外部接口需要我们进行对接,有的第三方给我们提供相关API,我们采用API直接调用即可,但是实际上,大部分公司内部的文档是一言难尽的。但是学习本身就是一个建模的过程!我来分享一下,我对外部接口对接的相关理解。

接口地址

接口地址本来没什么可说的,但是我们开发可能会有多个环境,一般分为dev、release环境。代码运行环境变化,实际只是Host发生变更。

目前我自己的方式是:在配置中心定义一个配置Base.Host=XXXXX。然后实际接口是项目启动时:对相关的接口地址进行拼接后缀:如 String baiduUrl = BaseHost + ”/zanglikun.com“; 如果配置发生变更,我们在写一个方法,去执行重新赋值baiduUrl。这样有个好处是:如果接口多,只需要更改一个配置,就能实现全局替换Host。例如:

@Data
@Component // 注册为组件
@Slf4j
public class TelecomApiConstant {
    // 定一个基础的host
    public static String BASE_HOST = "http://127.0.0.0:27010";

    // 接入一个动态替换的Host
    @Value("${telcom.host}")
    private String Base_Host_inConfig;

    // 本方法实际是制定配置文件发生了变动,调用setBaseHost() 实现动态切换
    @ApolloConfigChangeListener("application")
    public void changeConfig(ConfigChangeEvent changeEvent) {
        log.info("【Apollo配置文件】:发送变动了!");
        ConfigChange change = changeEvent.getChange("telcom.host");
        if (Objects.nonNull(change)) {
            Base_Host_inConfig = change.getNewValue(); // 替换新的配置值
            setBaseHost(); // 调用此方法替换其他BaseHost。这样就实现了动态切换环境了
        }
    }
   
    // 项目启动的时候 给相关接口赋值。同时也是个替换最新URL的方法
    @PostConstruct
    public void setBaseHost() {
        BASE_HOST = Base_Host_inConfig;
        // 获取边界数据
        GET_REGIONAL = BASE_HOST + "/api/datacenter/v1/gridViews/getRegional";
    }

    // 获取边界数据
    public static String GET_REGIONAL = BASE_HOST + "/api/datacenter/v1/gridViews/getRegional";
}

第二种方式是:配置中心写全了全部配置 比如 baiduAPI.searchName = https://www.baidu.com/zanglikun.com 这样有个好处是:针对每个接口,可单独控制环境。如果你有频繁切换接口环境的情况,可能就得人工切换了。本来想是全部替换 比如将 www.baidu.com 替换为 www.dev.baidu.com 去实现全部接口的切换。但是实际上,如果你配置有www.baidu.com字眼,可能会被同步替换,实际我不是太喜欢这种方式。

接口入参

我们先考虑到接口传参方式:如果你的接口有附件上传,就得使用请求头当放入application/form-data。详情可见https://www.zanglikun.com/13608.html说明。

如果入参只是文本文件,那就无所谓了。按照目标接口要求的Header、Body即可!

接口返回值

大部分接口返回的内容不会以Http请求的状态码给我们作为评判接口是否有效的结果。比如一个接口HTTP状态码是:200 。但是接口返回:{"success":false,"data":"","error_message":"account为空"}。这个场景肯定不能算所接口有效了!

所以想通过Http请求的状态码不是一个好方式。最终还得以具体业务接口响应的标志,如:code或者success相关字样为准。

{
  "success": true,
  "errCode": null,
  "errMessage": null,
}

接口响应数据转为我们需要的Java集合、对象

接口响应的Response对象的内容我们只需要:

String res = response.body().string();

它本身就是一个文本

            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
            }

结果处理如下

        Object data = JSONUtil.parseObj(s).get("data");
        List<Inspection> inspections = JSONUtil.toList(list.toString(), Inspection.class);

        CommunityBaseInfoVO baseVo = JSONUtil.toBean(data, CommunityBaseInfoVO.class);

请求日志

调用第三方接口一定要在工具类封装时:加上日志

请求头、请求体、响应结果。这是调用第三方接口必须要加入的。后续出现问题,也能迅速发现入参有问题,出参有问题!可以节省大量的排查问题的成本!

这是我从慧摩尔改造出来的工具类,使用的是OKHTTP

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Copy By Huimor-Project
 */
@Slf4j
public class HttpUtils {
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private static OkHttpClient client;

    static {
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
        client = builder.callTimeout(20, TimeUnit.SECONDS).build();
    }

    /**
     * HTTP POST JSON请求
     *
     * @param url       请求路径
     * @param jsonBody  请求参数
     * @param headers   请求头
     * @return 响应数据
     */
    public static String httpPostJsonRequest(String url, String jsonBody, Map<String, String> headers) {
        log.info("httpPostJsonRequest url: {}", url);
        log.info("httpPostJsonRequest params: {}", jsonBody);
        log.info("httpPostJsonRequest headers: {}", headers);
        RequestBody body = RequestBody.create(JSON, jsonBody);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Content-Type", "application/json;charset=utf-8")
                .build();
        if (null != headers && !headers.isEmpty()) {
            Request.Builder builder = request.newBuilder();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), null == entry.getValue() ? "" : entry.getValue());
            }
            request = builder.build();
        }
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                if (response.body() == null) {
                    log.error("httpPostJsonRequest service return null");
                }
                String responseText = response.body().string();
                log.info("httpPostJsonRequest response: {}", responseText);
                return responseText;
            } else {
                response.close();
                log.error("httpPostJsonRequest request was aborted");
            }
        } catch (IOException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return null;
    }


    /**
     * get 请求
     *
     * @param url
     * @return
     */
    public static String get(String url) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        try {
            Response response = client.newCall(request).execute();
            log.info("send request URL:{}" , url);
            if (response.isSuccessful()) {
                if (response.body() == null) {
                    log.error("httpPostJsonRequest service return null");
                }
                String responseText = response.body().string();
                log.info("get response: {}", responseText);
                return responseText;
            } else {
                response.close();
                log.info("get request was aborted");
            }
        } catch (IOException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return null;
    }

    /**
     * get 请求
     *
     * @param url
     * @return
     */
    public static String get(String url,HashMap<String, String> headers) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        if (null != headers && !headers.isEmpty()) {
            Request.Builder builder = request.newBuilder();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), null == entry.getValue() ? "" : entry.getValue());
            }
            request = builder.build();
        }
        try {
            Response response = client.newCall(request).execute();
            log.info("send request URL:{}" , url);
            if (response.isSuccessful()) {
                if (response.body() == null) {
                    log.error("httpPostJsonRequest service return null");
                }
                String responseText = response.body().string();
                log.info("get response: {}", responseText);
                return responseText;
            } else {
                response.close();
                log.info("get request was aborted");
            }
        } catch (IOException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return null;
    }

    /**
     * 重载方法 以便于懒省事,JSONUtil.toJsonStr(bodyParam)
     *
     * @param url       请求路径(String)
     * @param bodyParam 请求体(Object)
     * @param headers   请求头(HashMap)
     * @return 响应结果
     */
    public static String httpPostJsonRequest(String url, Object bodyParam, HashMap<String, String> headers) {
        log.info("httpPostJsonRequest url: {}", url);
        log.info("httpPostJsonRequest params: {}", bodyParam);
        log.info("httpPostJsonRequest headers: {}", headers);
        RequestBody body = RequestBody.create(JSON, JSONUtil.toJsonStr(bodyParam));
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Content-Type", "application/json;charset=utf-8")
                .build();
        if (null != headers && !headers.isEmpty()) {
            Request.Builder builder = request.newBuilder();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), null == entry.getValue() ? "" : entry.getValue());
            }
            request = builder.build();
        }
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                if (response.body() == null) {
                    log.error("httpPostJsonRequest service return null");
                }
                String responseText = response.body().string();
                log.info("httpPostJsonRequest response: {}", responseText);
                return responseText;
            } else {
                response.close();
                log.error("httpPostJsonRequest request was aborted");
            }
        } catch (IOException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return null;
    }
}
特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤