DefaultClient.java 9.9 KB
package com.xiniunet.open.api.client;

import com.xiniunet.open.api.client.contract.SessionEnum;
import com.xiniunet.open.api.client.internal.parser.json.ObjectJsonParser;
import com.xiniunet.open.api.client.internal.parser.xml.ObjectXmlParser;
import com.xiniunet.open.api.client.internal.util.*;

import java.io.IOException;
import java.util.Map;

/**

 */
public class DefaultClient implements XClient {
    private static final String APP_KEY = "app_key";
    private static final String FORMAT = "format";
    private static final String METHOD = "method";
    private static final String TIMESTAMP = "timestamp";
    private static final String VERSION = "v";
    private static final String SIGN = "sign";
    private static final String SIGN_METHOD = "sign_method";
    //    private static final String PARTNER_ID = "partner_id";
    private static final String SESSION = "session";
    private static final String PASSPORT_ID = "passportId";
    private static final String IDENTITY_ID = "identityId";
    private static final String SIMPLIFY = "simplify";

    private String serverUrl;
    private String appKey;
    private String appSecret;
    private String format = Constants.FORMAT_JSON;
    private String signMethod = Constants.SIGN_METHOD_MD5;

    private int connectTimeout = 3000;//3秒
    private int readTimeout = 60000;//60秒
    private boolean needCheckRequest = true; // 是否在客户端校验请求
    private boolean needEnableParser = true; // 是否对响应结果进行解释
    private boolean useSimplifyJson = false; // 是否采用精简化的JSON返回

    public DefaultClient(String serverUrl, String appKey, String appSecret) {
        this.appKey = appKey;
        this.appSecret = appSecret;
        this.serverUrl = serverUrl;
    }

    public DefaultClient(String serverUrl, String appKey, String appSecret, String format) {
        this(serverUrl, appKey, appSecret);
        this.format = format;
    }

    public DefaultClient(String serverUrl, String appKey, String appSecret, String format, int connectTimeout, int readTimeout) {
        this(serverUrl, appKey, appSecret, format);
        this.connectTimeout = connectTimeout;
        this.readTimeout = readTimeout;
    }

    public DefaultClient(String serverUrl, String appKey, String appSecret, String format, int connectTimeout, int readTimeout, String signMethod) {
        this(serverUrl, appKey, appSecret, format, connectTimeout, readTimeout);
        this.signMethod = signMethod;
    }

    @Override
    public <T extends XResponse> T execute(XRequest<T> request) throws ApiException {
        return execute(request, null);
    }

    @Override
    public <T extends XResponse> T execute(XRequest<T> request, String session) throws ApiException {
        return execute(request, SessionEnum.PASSPORT, session);
    }

    @Override
    public <T extends XResponse> T execute(XRequest<T> request, SessionEnum type, String session) throws ApiException {
        XParser<T> parser = null;
        if (this.needEnableParser) {
            if (Constants.FORMAT_XML.equals(this.format)) {
                parser = new ObjectXmlParser<T>(request.getResponseClass());
            } else {
                parser = new ObjectJsonParser<T>(request.getResponseClass(), this.useSimplifyJson);
            }
        }
        return _execute(request, parser, type, session);
    }

    private <T extends XResponse> T _execute(XRequest<T> request, XParser<T> parser, SessionEnum type, String session) throws ApiException {
        if (this.needCheckRequest) {
            try {
                request.check();
            } catch (ApiRuleException e) {
                T localResponse = null;
                try {
                    localResponse = request.getResponseClass().newInstance();
                } catch (Exception xe) {
                    throw new ApiException(xe);
                }
                localResponse.setErrorCode(e.getErrCode());
                localResponse.setMsg(e.getErrMsg());
                return localResponse;
            }
        }

        RequestParameters context = this.doPost(request, type, session);

        T tRsp = null;
        if (this.needEnableParser) {
            try {
                tRsp = parser.parse(context.getResponseBody());
                tRsp.setBody(context.getResponseBody());
            } catch (RuntimeException e) {
                ApiLogger.logBizError(context.getResponseBody());
                throw e;
            }
        } else {
            try {
                tRsp = request.getResponseClass().newInstance();
                tRsp.setBody(context.getResponseBody());
            } catch (Exception e) {
            }
        }

        tRsp.setParams(context.getApplicationParams());
        if (!tRsp.isSuccess()) {
            ApiLogger.logErrorScene(context, tRsp, appSecret);
        }
        return tRsp;
    }


    public <T extends XResponse> RequestParameters doPost(XRequest<T> request, SessionEnum type, String session) throws ApiException {
        RequestParameters requestParameters = new RequestParameters();
        XiniuHashMap appParams = new XiniuHashMap(request.getTextParams());
        requestParameters.setApplicationParams(appParams);

        // 添加协议级请求参数
        XiniuHashMap protocolMustParams = new XiniuHashMap();
        protocolMustParams.put(METHOD, request.getApiMethodName());
        protocolMustParams.put(VERSION, "1.0");
        protocolMustParams.put(APP_KEY, appKey);
        Long timestamp = request.getTimestamp();// 允许用户设置时间戳
        if (timestamp == null) {
            timestamp = System.currentTimeMillis();
        }
        System.out.println("timestamp = " + timestamp);

        protocolMustParams.put(TIMESTAMP, timestamp);// 因为沙箱目前只支持时间字符串,所以暂时用Date格式
        requestParameters.setProtocalMustParams(protocolMustParams);

        XiniuHashMap protocolOptParams = new XiniuHashMap();
        protocolOptParams.put(FORMAT, format);
        protocolOptParams.put(SIGN_METHOD, signMethod);
//        protocolOptParams.put(SESSION, session);
        if(type == SessionEnum.PASSPORT) {
            protocolOptParams.put(PASSPORT_ID, session);
        } else if(type == SessionEnum.IDENTITY) {
            protocolOptParams.put(IDENTITY_ID, session);
        }
//        protocalOptParams.put(PARTNER_ID, Constants.SDK_VERSION);
        if (this.useSimplifyJson) {
            protocolOptParams.put(SIMPLIFY, Boolean.TRUE.toString());
        }
        requestParameters.setProtocalOptParams(protocolOptParams);

        // 添加签名参数
        try {
            if (Constants.SIGN_METHOD_MD5.equals(signMethod)) {
                protocolMustParams.put(SIGN, ApiUtils.signTopRequestNew(requestParameters, appSecret, false));
            } else if (Constants.SIGN_METHOD_SHA1.equals(signMethod)) {
                protocolMustParams.put(SIGN, ApiUtils.signTopRequestNew(requestParameters, appSecret, true));
            } else {
                protocolMustParams.put(SIGN, ApiUtils.signTopRequest(requestParameters, appSecret));
            }
        } catch (IOException e) {
            throw new ApiException(e);
        }

        StringBuilder reqUrl = new StringBuilder(serverUrl);
        try {
            String sysMustQuery = WebUtils.buildQuery(requestParameters.getProtocalMustParams(), Constants.CHARSET_UTF8);
            String sysOptQuery = WebUtils.buildQuery(requestParameters.getProtocalOptParams(), Constants.CHARSET_UTF8);

            if (reqUrl.indexOf("?") != -1) {
                reqUrl.append("&");
            } else {
                reqUrl.append("?");
            }
            reqUrl.append(sysMustQuery);
            if (sysOptQuery != null && sysOptQuery.length() > 0) {
                reqUrl.append("&").append(sysOptQuery);
            }
            requestParameters.setRequestUrl(reqUrl.toString());
        } catch (IOException e) {
            throw new ApiException(e);
        }

        String rsp = null;
        try {
            // 是否需要上传文件
            if (request instanceof XUploadRequest) {
                XUploadRequest<T> uRequest = (XUploadRequest<T>) request;
                Map<String, FileItem> fileParams = ApiUtils.cleanupMap(uRequest.getFileParams());

                rsp = WebUtils.doPost(reqUrl.toString(), appParams, fileParams, Constants.CHARSET_UTF8, connectTimeout, readTimeout, request.getHeaderMap());
            } else {
                System.out.println("reqUrl="+reqUrl.toString());
                System.out.println("appParams"+appParams.toString());
                rsp = WebUtils.doPost(reqUrl.toString(), appParams, Constants.CHARSET_UTF8, connectTimeout, readTimeout, request.getHeaderMap());
            }
            requestParameters.setResponseBody(rsp);
        } catch (IOException e) {
            throw new ApiException(e);
        }
        return requestParameters;
    }

    /**
     * 是否在客户端校验请求参数。
     */
    public void setNeedCheckRequest(boolean needCheckRequest) {
        this.needCheckRequest = needCheckRequest;
    }

    /**
     * 是否把响应字符串解释为对象。
     */
    public void setNeedEnableParser(boolean needEnableParser) {
        this.needEnableParser = needEnableParser;
    }

    /**
     * 是否采用标准化的JSON格式返回。
     */
    public void setUseSimplifyJson(boolean useSimplifyJson) {
        this.useSimplifyJson = useSimplifyJson;
    }

    /**
     * 是否记录API请求错误日志。
     */
    public void setNeedEnableLogger(boolean needEnableLogger) {
        ApiLogger.setNeedEnableLogger(needEnableLogger);
    }

    /**
     * 是否忽略HTTPS证书校验。
     */
    public void setIgnoreSSLCheck(boolean ignore) {
        WebUtils.setIgnoreSSLCheck(ignore);
    }

    /**
     * 设置客户端与TOP网关的最大长连接数量。
     */
    public void setMaxKeepAliveConnections(int amount) {
        System.setProperty("http.maxConnections", String.valueOf(amount));
    }
}