一、工具类
package com.aisino.uwcloud.core.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.aisino.uwcloud.core.enums.CommonErrorCodeEnum;
import com.aisino.uwcloud.core.enums.MethodTypeEnum;
import com.aisino.uwcloud.core.invoice.request.OauthParam;
import com.aisino.uwcloud.core.invoice.response.XLBaseResponse;
import com.aisino.uwcloud.execption.XLException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.util.ParameterizedTypeImpl;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.IOException;
import java.lang.reflect.Type;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
/**
* 开票工具
*
* @author huan.liu
*/
public class RemoteCallHelper {
private static final Log log = LogFactory.get();
private RemoteCallHelper() {
throw new RuntimeException("RemoteCallHelper can not be new Instance !!!");
}
private final static Map<String, String> CACHE = CollUtil.newHashMap();
/**
* 初始化配置参数
*/
public static void initConfig(String ak, String sk, String tk, String ts, String domain) {
CACHE.put("ak", ak);
CACHE.put("sk", sk);
CACHE.put("tk", tk);
CACHE.put("ts", ts);
CACHE.put("domain", domain);
}
public static <R> XLBaseResponse<R> call(String taxId, String url, Object obj, Type... resultClass) {
String result;
if (CollUtil.isEmpty(CACHE)) {
throw new XLException("配置参数未初始化,请先初始化", CommonErrorCodeEnum.ERROR_00104_CONFIG_PARAM_ERROR);
}
try {
String params;
if (obj instanceof String) {
params = (String) obj;
} else {
params = JSON.toJSONString(obj);
}
result = doCall(taxId, url, params);
} catch (Exception e) {
log.error("Failed to real check, The exception is ", JSON.toJSONString(e));
throw new XLException("网络异常,请稍后再试", CommonErrorCodeEnum.ERROR_00199_SYSTEM_ERROR);
}
if (!StrUtil.isEmpty(result)) {
Type[] type = {XLBaseResponse.class};
type = ArrayUtil.append(type, resultClass);
return JSON.parseObject(result, buildType(type));
}
log.error(String.format("Failed to send, The request is %s\nThe response is empty", JSON.toJSONString(obj)));
throw new XLException("未知错误", CommonErrorCodeEnum.ERROR_00199_SYSTEM_ERROR);
}
private static String doCall(String taxId, String url, String content) throws IOException {
RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), content);
String requestUrl = CACHE.get("domain").concat(url);
String authStr = generateOauth(requestUrl, MethodTypeEnum.POST, CACHE.get("ak"), CACHE.get("sk"), CACHE.get("tk"), CACHE.get("ts"));
Request sendRequest = new Request.Builder()
.url(requestUrl)
.addHeader("x-kxl-client-company-taxNo", taxId)
.addHeader("Authorization", authStr)
.post(requestBody)
.build();
try {
Response sendResponse = XLClient.okClient.getOkHttpClient().newCall(sendRequest).execute();
String result = sendResponse.body().string();
log.info("call url success ! url :{} ,param:{}, result:{}", url, content, result);
return result;
} catch (IOException ex) {
log.error("call url error ! url :{} ,param:{}, error:{}", url, content, ex.toString());
throw ex;
}
}
private static String generateOauth(String url, MethodTypeEnum methodType, String appKey, String appSecret, String token, String tokenSecret) {
OauthParam oauthParam = new OauthParam();
oauthParam.setMethod(methodType.getName());
oauthParam.setUrl(url);
oauthParam.setOauthConsumerSecret(appSecret);
oauthParam.setOauthTokenSecret(tokenSecret);
LinkedHashMap<String, String> map = new LinkedHashMap();
String oauth_signature_method = "HMAC-SHA256";
String oauth_timestamp = Instant.now().getEpochSecond() + "";
String oauth_nonce = UUID.randomUUID().toString().replace("-", "");
String oauth_version = "1.0";
String oauth_signature = "";
map.put(UrlCodeUtils.encodeUrlUTF8("oauth_consumer_key"), UrlCodeUtils.encodeUrlUTF8(appKey));
map.put(UrlCodeUtils.encodeUrlUTF8("oauth_token"), UrlCodeUtils.encodeUrlUTF8(token));
map.put(UrlCodeUtils.encodeUrlUTF8("oauth_signature_method"), oauth_signature_method);
map.put(UrlCodeUtils.encodeUrlUTF8("oauth_timestamp"), UrlCodeUtils.encodeUrlUTF8(oauth_timestamp));
map.put(UrlCodeUtils.encodeUrlUTF8("oauth_nonce"), UrlCodeUtils.encodeUrlUTF8(oauth_nonce));
map.put(UrlCodeUtils.encodeUrlUTF8("oauth_version"), oauth_version);
map.put(UrlCodeUtils.encodeUrlUTF8("oauth_signature"), oauth_signature);
oauthParam.setParam(map);
oauth_signature = OauthSignUtils.sign(oauthParam);
return OauthSignUtils.genOauth(oauthParam, oauth_signature);
}
public static Type buildType(Type... types) {
ParameterizedTypeImpl beforeType = null;
if (types != null && types.length > 0) {
for (int i = types.length - 1; i > 0; i--) {
beforeType = new ParameterizedTypeImpl(new Type[]{beforeType == null ? types[i] : beforeType}, null, types[i - 1]);
}
}
return beforeType;
}
}
package com.aisino.uwcloud.core.invoice.response;
import com.aisino.uwcloud.execption.ErrorInfo;
import java.io.Serializable;
/**
* 响应封装
*
* @param <T>
* @author huan.liu
*/
public class XLBaseResponse<T> implements Serializable {
private static final long serialVersionUID = 1L;
private ErrorInfo status;
private T body;
private String requestNum;
public XLBaseResponse() {
}
public static <T> XLBaseResponse<T> newInstance(T body) {
XLBaseResponse<T> xlBaseResponse = new XLBaseResponse();
xlBaseResponse.setStatus(ErrorInfo.newInstance());
xlBaseResponse.setBody(body);
return xlBaseResponse;
}
public XLBaseResponse<T> requestNum(String requestNum) {
this.requestNum = requestNum;
return this;
}
public ErrorInfo getStatus() {
return this.status;
}
public XLBaseResponse setStatus(ErrorInfo status) {
this.status = status;
return this;
}
public T getBody() {
return this.body;
}
public XLBaseResponse setBody(T body) {
this.body = body;
return this;
}
public boolean isOk() {
return this.getStatus() != null && "200".equals(this.getStatus().getReturnCode());
}
public static XLBaseResponse setOk() {
XLBaseResponse xlBaseResponse = newInstance("");
return xlBaseResponse;
}
public static XLBaseResponse setError(Object msg) {
XLBaseResponse xlBaseResponse = newInstance(msg);
xlBaseResponse.getStatus().setReturnCode("9999");
xlBaseResponse.getStatus().setDescription(msg);
return xlBaseResponse;
}
public static XLBaseResponse setBasicError(Object msg) {
XLBaseResponse xlBaseResponse = newInstance((Object) null);
xlBaseResponse.getStatus().setReturnCode("9999");
xlBaseResponse.getStatus().setDescription(msg);
return xlBaseResponse;
}
public String getRequestNum() {
return this.requestNum;
}
public void setRequestNum(String requestNum) {
this.requestNum = requestNum;
}
}
二、调用方式
XLBaseResponse<ResDto> res = RemoteCallHelper.call(taxId, ISSUE, invoiceReqDto, ResDto.class);
XLBaseResponse<List<InfoResDto>> infoRes = RemoteCallHelper.call(sellerTaxId, INFO, infoReqDto, List.class, InfoResDto.class);