SDK调用

更新时间:
复制为 MD 格式

本文主要为您介绍安装独立部署Quick BI Java SDKJava示例。

安装Java SDK

  1. 安装Quick BI Java SDK。

  2. 在项目目录下的pom.xml文件中,添加Maven依赖。

    添加依赖后,Maven项目管理工具会自动下载相关JAR包。

              <!-- apache http client-->
                <dependency>
                    <groupId>org.apache.httpcomponents</groupId>
                    <artifactId>httpclient</artifactId>
                    <version>4.5.2</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.httpcomponents</groupId>
                    <artifactId>httpcore</artifactId>
                    <version>4.4.6</version>
                </dependency>
                <!--fastjson-->
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>fastjson</artifactId>
                    <version>1.2.83</version>
                </dependency>
    
                <!-- Logger -->
                <dependency>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                    <version>1.7.25</version>
                </dependency>
                <dependency>
                    <groupId>org.slf4j</groupId>
                    <artifactId>log4j-over-slf4j</artifactId>
                    <version>1.7.25</version>
                </dependency>
    
                <!-- 加密 解密 -->
                <dependency>
                    <groupId>commons-codec</groupId>
                    <artifactId>commons-codec</artifactId>
                    <version>1.7</version>
                </dependency>

Java示例

您可以按照以下流程完成Java SDK的调用:

  1. 创建IOpenAPIClient实例并初始化。

  2. 创建Request请求并设置参数。

  3. 发起请求并处理应答或异常(SDKException)。

import com.alibaba.quickbi.openapi.client.HttpMethod;
import com.alibaba.quickbi.openapi.client.HttpRequest;
import com.alibaba.quickbi.openapi.client.IOpenAPIClient;
import com.alibaba.quickbi.openapi.core.exception.SDKException;

public class ExampleTest {

    // 签名的ak/sk
    final static String ak = "2fe4fbd8-****-****-****-e92c7af083ea";
    final static String sk = "4eed92d1-****-****-****-4df526554bee";
    
    // host 域名
    final static String host = "http://local.das.biz.aliyun.test";
    // 根路径。(有定制根路径时设置 rootPath = "/XXX",一般为null)
    final static String rootPath = null;
    // rootpath是否加入签名的字符串拼接。
    final static boolean encodeRootPath = false;
    // 初识化客户端
    private static IOpenAPIClient client = 
        HttpClientFactory.buildDefaultClient(host, rootPath, encodeRootPath, 
                                             ak, sk, true);

    private static void testGet() throws SDKException {
        HttpRequest request = HttpRequest.build()
            .setUri("/openapi/v2/organization/user")
            .setMethod(HttpMethod.GET)
        // 接口的输入参数,具体以文档中为准
            .addParameter("pageNum", "1")
            .addParameter("pageSize", "10");
        // 是否开启调试模式,仅用于测试调试
        // request.addHeader("X-Gw-Debug", "true");
       
        String result = client.syncExecute(request);
        System.out.println(result);
    }

    public static void main(String[] args) throws Exception {
        testGet();
    }
}
                

get请求

以调用查询组织成员列表为例。

    /**
     * GET请求例子
     * @throws Exception
     */
    private static void testQueryOrganizationUserList() throws Exception {
        HttpRequest request = HttpRequest.build()
            .setUri("/openapi/v2/organization/user")
            .setMethod(HttpMethod.GET)
            .addParameter("pageNum", "1")
            .addParameter("pageSize", "10");
        
        // 是否开启调试模式,仅用于测试调试
        // request.addHeader("X-Gw-Debug", "true");
        String response = client.syncExecute(request);
        System.out.println(response);
    }

post请求

以调用添加组织成员为例。

   /**
     * post请求例子
     * @throws Exception
     */
    private static void testAddOrganizationUser() throws Exception {
        HttpRequest request = HttpRequest.build()
            .setUri("/openapi/v2/organization/user")
            .setMethod(HttpMethod.POST)
            .addParameter("accountName", "wy_*@163.com")
            .addParameter("nickName", "wy_test1")
            .addParameter("email", "wy_test*@163.com")
            .addParameter("phone", "05718877****")
            .addParameter("admin", "false");
        
        // 是否开启调试模式,仅用于测试调试
        // request.addHeader("X-Gw-Debug", "true");
        
        // 是否以content-type:application/x-www-form-urlencoded提交;除非接口特殊说明,否则不要赋值
        // request.setHttpContentType(FormatType.FORM);
        String response = client.syncExecute(request);
        System.out.println(response);
    }

附录:使用说明

HttpClientFactory静态工厂类

/**
 * OpenAPI的工厂类,构建OpenAPI客户端
 *
 * @author gengnan.wy
 * @date 2019/04/10
 */
public class HttpClientFactory {

    public static IOpenAPIClient buildDefaultClient(String host, String ak, 
                                                    String sk, boolean debug) {
        return buildClient(host, null, false, ak, sk, 
                           HttpClientConfig.getDefault(), debug);
    }

    public static IOpenAPIClient buildDefaultClient(String host, String rootPath,
                                                    boolean encodeRootPath, 
                                                    String ak, String sk, 
                                                    boolean debug) {
        return buildClient(host, rootPath, encodeRootPath, ak, sk, 
                           HttpClientConfig.getDefault(), debug);
    }

    /**
     * 构建默认的OpenAPI客户端。引用时,请使用单例模式
     *
     * @param host     域名。
     * @param rootPath 接口根路径。最终完成的请求URL = host + rootPath + 调用时指定的URI。
     * @param encodeRootPath 根路径是否加入到签名字符串的拼接。
     *                       如果为true,则加入签名的接口完整路径为:rootPath + 调用时指定的URI。
     *                       如果为false,则加入签名的接口完整路径为: 调用时指定的URI。
     * @param ak             ak,对应Quick BI组织管理下识别码中的AccessKey ID
     * @param sk             sk,对应Quick BI组织管理下识别码中的AccessKey Secret
     * @param debug          是否开启debug模式,如果开启为true,在请求签名不通过时,则可以通过
     *                       返回的response的请求头中,获取后端的拼接的字符串以及签名字符串,
     *                       用于比对调试。SDK会在日志中打印出服务器返回的签名信息
     * @return
     */
    public static IOpenAPIClient buildClient(String host, String rootPath, 
                                             boolean encodeRootPath, 
                                             String ak, String sk,
                                             HttpClientConfig httpClientConfig, 
                                             boolean debug) {
        if (null == host || null == ak || null == sk) {
            throw new IllegalArgumentException("can not init client, host/ak/sk can not be null");
        }
        OpenApiClientHttpClient client = 
            new OpenApiClientHttpClient(httpClientConfig, host, rootPath, 
                                        encodeRootPath, ak, sk, debug);
        try {
            client.init(httpClientConfig);
            return client;
        } catch (ClientException e) {
            throw new IllegalStateException("init http client failed", e);
        }
    }
}


/**
 * OpenAPI client提供的请求方法
 * 1:提供基础http、https方法封装
 * 2:签名支持
 * 3:返回结果的封装
 */
public interface IOpenAPIClient {
    /**
     * 同步请求。以String形式返回结果集
     *
     * @throws SDKException
     */
    String syncExecute(HttpRequest request) throws SDKException;

    /**
     * 异步请求。以String形式返回结果集
     *
     * @throws SDKException
     */
    String asyncExecute(HttpRequest request) throws SDKException;

    /**
     * 同步请求。指定结果集格式
     *
     * @throws SDKException
     */
    <T> T syncExecute(HttpRequest request, Class<T> object) throws SDKException;

    /**
     * 异步请求。指定结果集格式
     *
     * @throws SDKException
     */
    <T> T asyncExecute(HttpRequest request, Class<T> object) throws SDKException;
}

HttpRequest & HttpResponse

说明

httpRequest是请求体参数的封装,包含了URI,httpMethod,请求头headers, 以及参数parameters。HttpResponse是返回的封装,包含了返回的请求头headers,状态码code、以及服务器返回的结果response。

public class HttpRequest implements Serializable {

    /**
     * uri;不包含query参数
     */
    private String uri;

    private HttpMethod method;

    /**
     * 额外自定义headers。一般为空。
     * 注意一下特例:
     * 1:Content-Type指定不起效果。底层仅默认两种appliaction/json和application/x-www-url-encoded;
     * 2:如果有扩展签名字段,请指定X-Gw-ExtHeaders
     */
    private Map<String, String> headers = new HashMap<String, String>();

    /**
     * get/delete不允许包含entity内容,因此,该参数解析成URL路径参数。
     * post/put,根据httpContentType,解析成json串格式、或者表单格式,附属在entity中
     */
    protected Map<String, String> parameters = new HashMap<String, String>();

    /**
    * http请求头Content-Type。默认是application/json的格式
    */
    private FormatType httpContentType = FormatType.JSON;

    // GETTER and SETTER
}

public class HttpResponse implements Serializable {

    /**
     * http请求的状态码,例如200, 404
     */
    int code;

    /**
     * http请求返回的服务器结果
     */
    String response;

    /**
     * 返回的请求头
     */
    Map<String, String> headers;
    
    // SETTER and GETTER
}

如何解决errorCode: OE10010104, errorMsg: signature error报错?

问题描述

开启调试模式时,通过SDK调用,服务器出现errorCode: OE10010104, errorMsg: signature error错误。

可能原因及解决方案

此为签名失败。主要从以下几个方面排查:

  • 查看AccessKey IDAccessKey Secret是否正确。

    解决方案:在开发者中心首页查看组织识别码

    image

  • 判断接口的URI是否携带域名。

    解决方案:URI正确格式不携带域名。

  • 确认请求的contentType是否正确。

    解决方案:

    • 如果是表单传参,则正确的contentTyperequest.setHttpContentType(FormatType.FORM)

    • 如果是JSON传参,则正确的contentType request.setHttpContentType(FormatType.JSON)

  • 开启调试模式,对比本地的签名拼接字符串和服务器返回的签名拼接字符串。

    解决方案:

    1. 在赋值request时,添加一个debug请求头,如下:

      request.addHeader("X-Gw-Debug", "true");
    2. 在接口返回处打断点,可以从response中的请求头中,得到R-Gw-String-To-Sign请求头,该字段为服务器签名前的拼接字符串,对比本地拼接的字符串,便可以确定签名校验不通过的原因。拼接字符串待拼接字段

如何解决Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: None of the TrustManagers trust this certificate chain报错?

问题描述

SDK使用HTTPS调用时,出现Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: None of the TrustManagers trust this certificate chain报错。

解决方案

HttpClientConfig httpClientConfig = HttpClientConfig.getDefault();
// 开启证书忽略
httpClientConfig.setIgnoreSSLCerts(true);
client = HttpClientFactory.buildClient(host, rootPath, false, ak, sk, httpClientConfig, true);