com.aliyun.dc.opplat.sdk.api.AbstractClient Maven / Gradle / Ivy
/**
* Alipay.com Inc. Copyright (c) 2004-2020 All Rights Reserved.
*/
package com.aliyun.dc.opplat.sdk.api;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import javax.net.ssl.SSLException;
import com.aliyun.dc.opplat.sdk.api.common.DcLabHashMap;
import com.aliyun.dc.opplat.sdk.api.common.OpplatConstants;
import com.aliyun.dc.opplat.sdk.api.common.SignChecker;
import com.aliyun.dc.opplat.sdk.api.common.Signer;
import com.aliyun.dc.opplat.sdk.api.exception.OpplatApiException;
import com.aliyun.dc.opplat.sdk.api.internal.parser.json.ObjectJsonParser;
import com.aliyun.dc.opplat.sdk.api.internal.parser.xml.ObjectXmlParser;
import com.aliyun.dc.opplat.sdk.api.internal.util.RequestParametersHolder;
import com.aliyun.dc.opplat.sdk.api.internal.util.WebUtils;
import com.aliyun.dc.opplat.sdk.api.internal.util.json.JSONWriter;
import com.aliyun.dc.opplat.sdk.api.request.OpplatRequest;
import com.aliyun.dc.opplat.sdk.api.response.BaseOpplatResponse;
import com.aliyun.dc.opplat.sdk.api.utils.OpenApiSignature;
import com.aliyun.dc.opplat.sdk.api.utils.StringUtils;
/**
* SDK端执行抽象类
*
* @author changlei.qcl
* @version $Id: AbstractClient.java, v 0.1 2020年07月28日 2:36 PM changlei.qcl Exp $
*/
public abstract class AbstractClient implements OpplatClient {
private String serverUrl;
private String appId;
private String format = OpplatConstants.FORMAT_JSON;
private String signType = OpplatConstants.SIGN_TYPE_RSA;
private String charset;
private int connectTimeout = 3000;
private int readTimeout = 15000;
public AbstractClient(String serverUrl, String appId, String format,
String charset, String signType) {
this.serverUrl = serverUrl;
this.appId = appId;
if (!StringUtils.isEmpty(format)) {
this.format = format;
}
this.charset = charset;
if (!StringUtils.isEmpty(signType)) {
this.signType = signType;
}
}
@Override
public T execute(OpplatRequest request) throws OpplatApiException {
OpplatParser parser = null;
if (OpplatConstants.FORMAT_JSON.equals(this.format)) {
parser = new ObjectJsonParser(request.getResponseClass());
} else {
parser = new ObjectXmlParser(request.getResponseClass());
}
return actualExecute(request, parser);
}
private T actualExecute(OpplatRequest request, OpplatParser parser) throws OpplatApiException {
long beginTime = System.currentTimeMillis();
Map rt = doPost(request);
if (rt == null) {
return null;
}
Map costTimeMap = new HashMap();
if (rt.containsKey("prepareTime")) {
costTimeMap.put("prepareCostTime", (Long) (rt.get("prepareTime")) - beginTime);
if (rt.containsKey("requestTime")) {
costTimeMap.put("requestCostTime", (Long) (rt.get("requestTime")) - (Long) (rt.get("prepareTime")));
}
}
// 暂无加密的需求,所以返回报文即可见报文
String responseContent = (String) rt.get("rsp");
T tRsp = parser.parse(responseContent);
checkResponseSign(request, parser, responseContent);
if (costTimeMap.containsKey("requestCostTime")) {
costTimeMap.put("postCostTime", System.currentTimeMillis() - (Long) (rt.get("requestTime")));
}
tRsp.setParams((DcLabHashMap) rt.get("textParams"));
return tRsp;
}
private void checkResponseSign(OpplatRequest request,
OpplatParser parser,
String responseBody) throws OpplatApiException {
if (getSignChecker() != null) {
// 解析出业务返回参数
SignItem signItem = parser.getSignItem(request, responseBody);
if (signItem == null) {
throw new OpplatApiException("sign check fail: Body is Empty!");
}
// 仅针对签名不为空
if (!StringUtils.isEmpty(signItem.getSign())) {
boolean rsaCheckContent = getSignChecker().check(signItem.getSignSourceDate(),
signItem.getSign(), this.signType, this.charset);
if (!rsaCheckContent) {
// 针对JSON \/问题,替换/后再尝试做一次验证
if (!StringUtils.isEmpty(signItem.getSignSourceDate())
&& signItem.getSignSourceDate().contains("\\/")) {
String srouceData = signItem.getSignSourceDate().replace("\\/", "/");
boolean jsonCheck = getSignChecker().check(srouceData, signItem.getSign(),
this.signType, this.charset);
if (!jsonCheck) {
throw new OpplatApiException(
"sign check fail: check Sign and Data Fail!JSON also!");
}
} else {
throw new OpplatApiException("sign check fail: check Sign and Data Fail!");
}
}
}
}
}
/**
* 发送POST请求
*
* @param request
* @param
* @return
* @throws OpplatApiException
*/
private Map doPost(OpplatRequest request) throws OpplatApiException {
Map result = new HashMap();
RequestParametersHolder requestHolder = getRequestHolderWithSign(request);
String url = getRequestUrl(requestHolder);
result.put("prepareTime", System.currentTimeMillis());
String rsp = null;
try {
rsp = WebUtils.doPost(url, requestHolder.getApplicationParams(), charset,
connectTimeout, readTimeout, null, 0);
} catch (SSLException e) {
throw new OpplatApiException(e);
} catch (IOException e) {
throw new OpplatApiException(e);
}
result.put("requestTime", System.currentTimeMillis());
result.put("rsp", rsp);
result.put("textParams", requestHolder.getApplicationParams());
result.put("protocalMustParams", requestHolder.getProtocalMustParams());
result.put("protocalOptParams", requestHolder.getProtocalOptParams());
result.put("url", url);
return result;
}
/**
* 组装接口参数,处理加密、签名逻辑
*
* @param request
* @return
* @throws OpplatApiException
*/
private RequestParametersHolder getRequestHolderWithSign(OpplatRequest> request)
throws OpplatApiException {
RequestParametersHolder requestHolder = new RequestParametersHolder();
DcLabHashMap appParams = new DcLabHashMap(request.getTextParams());
// 仅当API包含biz_content参数且值为空时,序列化bizModel填充bizContent
try {
if (request.getClass().getMethod("getBizContent") != null
&& StringUtils.isEmpty(appParams.get(OpplatConstants.BIZ_CONTENT_KEY))
&& request.getBizModel() != null) {
appParams.put(OpplatConstants.BIZ_CONTENT_KEY,
new JSONWriter().write(request.getBizModel(), true));
}
} catch (NoSuchMethodException e) {
// 找不到getBizContent则什么都不做
} catch (SecurityException e) {
//
}
requestHolder.setApplicationParams(appParams);
if (StringUtils.isEmpty(charset)) {
charset = OpplatConstants.CHARSET_UTF8;
}
DateFormat df = new SimpleDateFormat(OpplatConstants.DEFAULT_DATE_FORMAT);
df.setTimeZone(TimeZone.getTimeZone(OpplatConstants.DATE_TIMEZONE));
DcLabHashMap protocalMustParams = new DcLabHashMap();
protocalMustParams.put(OpplatConstants.API_REQ_APP_ID, this.appId);
protocalMustParams.put(OpplatConstants.API_REQ_CHARSET, this.charset);
protocalMustParams.put(OpplatConstants.API_REQ_FORMAT, this.format);
protocalMustParams.put(OpplatConstants.API_REQ_TIME, df.format(new Date(System.currentTimeMillis())));
protocalMustParams.put(OpplatConstants.API_REQ_SIGN_TYPE, this.signType);
protocalMustParams.put(OpplatConstants.API_REQ_FUNC, request.getApiMethodName());
protocalMustParams.put(OpplatConstants.API_REQ_VERSION, request.getApiVersion());
requestHolder.setProtocalMustParams(protocalMustParams);
if (null != this.signType) {
String signContent = OpenApiSignature.getSignatureContent(requestHolder);
protocalMustParams.put(OpplatConstants.SIGN, getSigner().sign(signContent, signType, charset));
} else {
protocalMustParams.put(OpplatConstants.SIGN, "");
}
return requestHolder;
}
/**
* 获取POST请求的base url
*
* @param requestHolder
* @return
* @throws OpplatApiException
*/
private String getRequestUrl(RequestParametersHolder requestHolder) throws OpplatApiException {
StringBuilder urlSb = new StringBuilder(serverUrl);
try {
String sysMustQuery = WebUtils.buildQuery(requestHolder.getProtocalMustParams(), charset);
String sysOptQuery = WebUtils.buildQuery(requestHolder.getProtocalOptParams(), charset);
urlSb.append("?");
urlSb.append(sysMustQuery);
if (sysOptQuery != null && sysOptQuery.length() > 0) {
urlSb.append("&");
urlSb.append(sysOptQuery);
}
} catch (IOException e) {
throw new OpplatApiException(e);
}
return urlSb.toString();
}
/**
* Setter method for property serverUrl.
*
* @param serverUrl value to be assigned to property serverUrl
*/
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
/**
* Setter method for property appId.
*
* @param appId value to be assigned to property appId
*/
public void setAppId(String appId) {
this.appId = appId;
}
/**
* Setter method for property format.
*
* @param format value to be assigned to property format
*/
public void setFormat(String format) {
this.format = format;
}
/**
* Setter method for property signType.
*
* @param signType value to be assigned to property signType
*/
public void setSignType(String signType) {
this.signType = signType;
}
/**
* Setter method for property charset.
*
* @param charset value to be assigned to property charset
*/
public void setCharset(String charset) {
this.charset = charset;
}
/**
* Setter method for property connectTimeout.
*
* @param connectTimeout value to be assigned to property connectTimeout
*/
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
/**
* Setter method for property readTimeout.
*
* @param readTimeout value to be assigned to property readTimeout
*/
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
public abstract SignChecker getSignChecker();
public abstract Signer getSigner();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy