当前位置: 首页 > news >正文

网站人员队伍建设薄弱网络联盟推广

网站人员队伍建设薄弱,网络联盟推广,软件商店安装免费下载,企业网站建设文档目录 一、概述 二、 网关的使用 2.1 核心代码 三、腾讯云SDK依赖包的改造 一、概述 此网关主要用于协调腾讯云SDK调用的QPS消耗#xff0c;使得多个腾讯云用户资源能得到最大限度的利用。避免直接使用腾讯云SDK 时#xff0c;在较大并发情况下导致接口调用异常。网关的工…目录 一、概述 二、 网关的使用 2.1 核心代码 三、腾讯云SDK依赖包的改造 一、概述 此网关主要用于协调腾讯云SDK调用的QPS消耗使得多个腾讯云用户资源能得到最大限度的利用。避免直接使用腾讯云SDK 时在较大并发情况下导致接口调用异常。网关的工作流程如下图所示 如上图所示各个客户端在发起腾讯云SDK调用时请求统一先发到网关网关会根据现有的腾讯云账户资源使用情况通过负载均衡算法选择一个合适的腾讯云账户来执行请求将请求转发到腾讯云服务从而保证了腾讯云用户资源的最大利用。在这个过程中如果暂时未找到可用的腾讯云用户则会阻塞线程直到有可用的账户时再将线程唤醒放行避免了在较大并发量时直接调用SDK而导致接口报错的情况发生。 二、 网关的使用 2.1 核心代码 RequestLimitFilter.java package com.tencentcloudapi.gateway.filter;import com.tencentcloudapi.common.Sign; import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.gateway.api.dto.UserInfo; import com.tencentcloudapi.gateway.api.service.UserManageService; import io.micrometer.common.util.StringUtils; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono;import javax.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; import java.sql.Date; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.Semaphore;/*** Description 限流过滤器* Author miller.Lai* Date 2023-11-06 10:23*/ Component Slf4j public class RequestLimitFilter implements GlobalFilter, Ordered {Resourceprivate UserManageService userManageService;Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request exchange.getRequest();// 打印请求路径String requestUri request.getPath().pathWithinApplication().value();log.info(接受到请求请求路径{}, requestUri);ListString authorizationList request.getHeaders().get(authorization);ListString actionList request.getHeaders().get(X-TC-Action);// 如果请求头中存在 authorization 信息则要进行替换以适应现有的接口TPS限制策略if (!CollectionUtils.isEmpty(authorizationList) StringUtils.isNotEmpty(authorizationList.get(0))!CollectionUtils.isEmpty(actionList) StringUtils.isNotEmpty(actionList.get(0))) {UserInfo userInfo new UserInfo();// 接口名称String action null;try {action actionList.get(0);log.info(当前调用API名称{}, action);// 获取可用的腾讯秘钥这是一个阻塞方法userInfo userManageService.getAvailableUserInfo(action);String secretId userInfo.getSecretInfo().getSecretId();String secretKey userInfo.getSecretInfo().getSecretKey();// 根据可用的秘钥对请求头中的认证信息做重新生成String signedHeaders content-type;host;SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd);sdf.setTimeZone(TimeZone.getTimeZone(UTC));// 接口请求所在秒钟String timestamp String.valueOf(System.currentTimeMillis() / 1000L);String date sdf.format(new Date(Long.valueOf(timestamp 000)));String service request.getHeaders().get(service) ! null ? request.getHeaders().get(service).get(0) : ;String credentialScope date / service /tc3_request;String stringToSign request.getHeaders().get(stringToSign) ! null ? new String(Base64.getDecoder().decode(Objects.requireNonNull(request.getHeaders().get(stringToSign)).get(0).getBytes())) : ;try {byte[] secretDate Sign.hmac256((TC3 secretKey).getBytes(StandardCharsets.UTF_8), date);byte[] secretService Sign.hmac256(secretDate, service);byte[] secretSigning Sign.hmac256(secretService, tc3_request);String signature DatatypeConverter.printHexBinary(Sign.hmac256(secretSigning, stringToSign)).toLowerCase();String authorization TC3-HMAC-SHA256 Credential secretId / credentialScope , SignedHeaders signedHeaders , Signature signature;exchange.getRequest().mutate().headers(httpHeaders - {// 去除自定义的请求头httpHeaders.remove(service);httpHeaders.remove(stringToSign);// 去除不合法的认证信息httpHeaders.remove(authorization);// 塞入有效的认证信息httpHeaders.add(authorization, authorization);});} catch (TencentCloudSDKException e) {throw new RuntimeException(e);}log.info(线程 {} 的请求时间:{} 毫秒,secretId:{},Thread.currentThread().getName(),System.currentTimeMillis(),secretId);UserInfo finalUserInfo userInfo;String finalAction action;// 如果上述过着正常获取信号量的许可String hasAcquired userManageService.getHasAcquiredThreadLocal().get();userManageService.getHasAcquiredThreadLocal().remove();return chain.filter(exchange).then( Mono.fromRunnable(() - {// 接口逻辑执行完毕后释放信号量锁if(1.equals(hasAcquired)){finalUserInfo.getInterfaceInfo(finalAction).getSemaphore().release();log.info(线程 {} 已释放线程锁,Thread.currentThread().getName());}}));} catch (Exception e) {// 在发生错误时释放信号量锁// 将当前线程标记为已获取许可String hasAcquired userManageService.getHasAcquiredThreadLocal().get();if(1.equals(hasAcquired)){userInfo.getInterfaceInfo(action).getSemaphore().release();userManageService.getHasAcquiredThreadLocal().remove();log.info(线程 {} 已释放线程锁,Thread.currentThread().getName());}throw new RuntimeException(e);}}else{return chain.filter(exchange);}}Overridepublic int getOrder() {return 1;} }UserManageServiceImpl.java package com.tencentcloudapi.gateway.api.service;import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.tencentcloudapi.gateway.api.dto.UserInfo; import com.tencentcloudapi.gateway.api.dto.InterfaceInfo; import io.micrometer.common.util.StringUtils; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service;import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit;/*** author Miller.Lai* description: 腾讯云用户管理实现类* date 2024-01-25 17:13:10*/ Service public class UserManageServiceImpl implements UserManageService {private ListUserInfo userInfos;Value(${tencentcloud.api.authorization.file:})private String authorizationJsonUrl;private ThreadLocalString hasAcquiredThreadLocal ;public ThreadLocalString getHasAcquiredThreadLocal() {return hasAcquiredThreadLocal;}PostConstructpublic void init(){try {InputStream inputStreams null;// 如果有指定authorization文件路径则按指定的路径找配置文件if (StringUtils.isNotBlank(authorizationJsonUrl)) {inputStreams new FileInputStream(authorizationJsonUrl);} else {// 从resource目录下加载JSON文件Resource resource new ClassPathResource(authorization.json);inputStreams resource.getInputStream();}// 使用Jackson的ObjectMapper将JSON数组内容映射为List对象ObjectMapper objectMapper new ObjectMapper();userInfos objectMapper.readValue(inputStreams, new TypeReference() {});hasAcquiredThreadLocal new ThreadLocal();} catch (IOException e) {throw new RuntimeException(e);}}/*** 随机获取一个可用的用户* param action* return*/Overridepublic UserInfo getAvailableUserInfo(String action) {// 可用的用户列表ListUserInfo availableUserInfos new ArrayList();// 计算总权重即总并发量int totalWeight 0;// 过滤可用的腾讯用户,过滤条件: action匹配for (int i 0; i userInfos.size(); i) {UserInfo userInfo userInfos.get(i);// 当前用户是否可用boolean available false;for (int j 0; j userInfo.getInterfaces().size(); j) {InterfaceInfo interfaceInfo userInfo.getInterfaces().get(j);if(interfaceInfo.getAction().equals(action)){available true;totalWeight interfaceInfo.getMaxTPS();break;}}// 如果当前用户可用则加入列表if(available){availableUserInfos.add(userInfo);}}// 如果没找到可用用户说明用户接口配置文件存在问题if(availableUserInfos.size() 0 ){throw new RuntimeException(未找到可用的腾讯用户请检查接口配置文件);}// 根据总权重生成权重随机数0 ~ totalWeight-1int randomWeight new Random().nextInt(totalWeight);// 根据权重值选择对应的用户int currentWeight 0;for (int i 0; i availableUserInfos.size(); i) {UserInfo userInfo availableUserInfos.get(i);for (int j 0; j userInfo.getInterfaces().size(); j) {InterfaceInfo interfaceInfo userInfo.getInterfaces().get(j);// 找到对应的接口if (interfaceInfo.getAction().equals(action)) {currentWeight interfaceInfo.getMaxTPS();// 如果当前接口的当前权重 随机权重 则使用当前用户if (currentWeight randomWeight) {// 给线程加锁这是一个阻塞方法如果当前用户的并发数达到上限则当前线程会被阻塞try {interfaceInfo.getSemaphore().tryAcquire(30, TimeUnit.SECONDS);// 将当前线程标记为已获取许可hasAcquiredThreadLocal.set(1);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {return userInfo;}}break;}}}return null;} }authorization.json [{secretInfo: {secretId: AKIDpiYK2xxxxxxxxxxxxxxxxxxbUyOk2W,secretKey: dFlSKDBDXXXXXXXXXXXXXXXXXXYdyBE5},interfaces: [{action: RecognizeTableAccurateOCR,maxTPS: 2},{action: VehicleLicenseOCR,maxTPS: 10},{action: DriverLicenseOCR,maxTPS: 10},{action: MLIDPassportOCR,maxTPS: 5},{action: HmtResidentPermitOCR,maxTPS: 20},{action: MainlandPermitOCR,maxTPS: 20}]},{secretInfo: {secretId: AKIDJh9fxxxxxxxxxxxxxxxxxxxxxv8IOR,secretKey: 00HaowzxxxxxxxxxxxxxxxxxxxxxjMp8b},interfaces: [{action: RecognizeTableAccurateOCR,maxTPS: 2},{action: VehicleLicenseOCR,maxTPS: 10},{action: DriverLicenseOCR,maxTPS: 10},{action: MLIDPassportOCR,maxTPS: 5},{action: HmtResidentPermitOCR,maxTPS: 20},{action: MainlandPermitOCR,maxTPS: 20}]} ] application-dev.yml spring:application:name: uap-gatewaycloud:gateway:routes:- id: tencentcloud-routeuri: https://ocr.tencentcloudapi.compredicates:- Path/tencentcloudapi/**filters:- StripPrefix1main:web-application-type: reactive server:port: 9000# 腾讯云用户接口权限配置文件 #tencentcloud: # api: # authorization: # file: d://authorization.json三、腾讯云SDK依赖包的改造 修改 com.tencentcloudapi.common.AbstractClient 类中 REMOTE_SERVER_ADDRESS 的值指向实际的网关地址如下所示 /** Copyright (c) 2018 THL A29 Limited, a Tencent company. All Rights Reserved.** Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on an* AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY* KIND, either express or implied. See the License for the* specific language governing permissions and limitations* under the License.*/package com.tencentcloudapi.common;import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.common.http.HttpConnection; import com.tencentcloudapi.common.profile.ClientProfile; import com.tencentcloudapi.common.profile.HttpProfile; import okhttp3.*; import okhttp3.Headers.Builder;import javax.crypto.Mac; import javax.net.ssl.SSLContext; import javax.xml.bind.DatatypeConverter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.sql.Date; import java.text.SimpleDateFormat; import java.util.*;public abstract class AbstractClient {/*** 远程服务地址根据实际情况修改* 格式为http://ip:port/tencentcloudapi*/public static String REMOTE_SERVER_ADDRESS http://localhost:9000/tencentcloudapi;public static final int HTTP_RSP_OK 200;public static final String SDK_VERSION SDK_JAVA_3.1.699;private Credential credential;private ClientProfile profile;private String endpoint;private String service;private String region;private String path;private String sdkVersion;private String apiVersion;public Gson gson;private TCLog log;private HttpConnection httpConnection;public AbstractClient(String endpoint, String version, Credential credential, String region) {this(endpoint, version, credential, region, new ClientProfile());}static {String remoteServerAddress System.getenv(REMOTE_SERVER_ADDRESS);if(remoteServerAddress ! null){AbstractClient.REMOTE_SERVER_ADDRESS remoteServerAddress;}}public AbstractClient(String endpoint,String version,Credential credential,String region,ClientProfile profile) {this.credential credential;this.profile profile;this.endpoint endpoint;this.service endpoint.split(\\.)[0];this.region region;this.path /;this.sdkVersion AbstractClient.SDK_VERSION;this.apiVersion version;this.gson new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();this.log new TCLog(getClass().getName(), profile.isDebug());this.httpConnection new HttpConnection(this.profile.getHttpProfile().getConnTimeout(),this.profile.getHttpProfile().getReadTimeout(),this.profile.getHttpProfile().getWriteTimeout());this.httpConnection.addInterceptors(this.log);this.trySetProxy(this.httpConnection);warmup();}public void setRegion(String region) {this.region region;}public String getRegion() {return this.region;}public void setClientProfile(ClientProfile profile) {this.profile profile;}public ClientProfile getClientProfile() {return this.profile;}public void setCredential(Credential credential) {this.credential credential;}public Credential getCredential() {return this.credential;}/*** Use post/json with tc3-hmac-sha256 signature to call any action. Ignore request method and* signature method defined in profile.** param action Name of action to be called.* param jsonPayload Parameters of action serialized in json string format.* return Raw response from API if request succeeded, otherwise an exception will be raised* instead of raw response* throws TencentCloudSDKException*/public String call(String action, String jsonPayload) throws TencentCloudSDKException {HashMapString, String headers this.getHeaders();headers.put(X-TC-Action, action);headers.put(Content-Type, application/json; charsetutf-8);byte[] requestPayload jsonPayload.getBytes(StandardCharsets.UTF_8);String authorization this.getAuthorization(headers, requestPayload);headers.put(Authorization, authorization);String url REMOTE_SERVER_ADDRESS this.path;return this.getResponseBody(url, headers, requestPayload);}/*** Use post application/octet-stream with tc3-hmac-sha256 signature to call specific action.* Ignore request method and signature method defined in profile.** param action Name of action to be called.* param headers Parameters of the action, will be put in http header.* param body octet-stream binary body.* return Raw response from API if request succeeded, otherwise an exception will be raised* instead of raw response* throws TencentCloudSDKException*/public String callOctetStream(String action, HashMapString, String headers, byte[] body)throws TencentCloudSDKException {headers.putAll(this.getHeaders());headers.put(X-TC-Action, action);headers.put(Content-Type, application/octet-stream; charsetutf-8);String authorization this.getAuthorization(headers, body);headers.put(Authorization, authorization);String url REMOTE_SERVER_ADDRESS this.path;return this.getResponseBody(url, headers, body);}private HashMapString, String getHeaders() {HashMapString, String headers new HashMapString, String();String timestamp String.valueOf(System.currentTimeMillis() / 1000);headers.put(X-TC-Timestamp, timestamp);headers.put(X-TC-Version, this.apiVersion);headers.put(X-TC-Region, this.getRegion());headers.put(X-TC-RequestClient, SDK_VERSION);headers.put(Host, this.getEndpoint());String token this.credential.getToken();if (token ! null !token.isEmpty()) {headers.put(X-TC-Token, token);}if (this.profile.isUnsignedPayload()) {headers.put(X-TC-Content-SHA256, UNSIGNED-PAYLOAD);}if (null ! this.profile.getLanguage()) {headers.put(X-TC-Language, this.profile.getLanguage().getValue());}return headers;}private String getAuthorization(HashMapString, String headers, byte[] body)throws TencentCloudSDKException {String endpoint this.getEndpoint();// always use post tc3-hmac-sha256 signature process// okhttp always set charset even we dont specify it,// to ensure signature be correct, we have to set it here as well.String contentType headers.get(Content-Type);byte[] requestPayload body;String canonicalUri /;String canonicalQueryString ;String canonicalHeaders content-type: contentType \nhost: endpoint \n;String signedHeaders content-type;host;String hashedRequestPayload ;if (this.profile.isUnsignedPayload()) {hashedRequestPayload Sign.sha256Hex(UNSIGNED-PAYLOAD.getBytes(StandardCharsets.UTF_8));} else {hashedRequestPayload Sign.sha256Hex(requestPayload);}String canonicalRequest HttpProfile.REQ_POST \n canonicalUri \n canonicalQueryString \n canonicalHeaders \n signedHeaders \n hashedRequestPayload;String timestamp headers.get(X-TC-Timestamp);SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd);sdf.setTimeZone(TimeZone.getTimeZone(UTC));String date sdf.format(new Date(Long.valueOf(timestamp 000)));String service endpoint.split(\\.)[0];String credentialScope date / service / tc3_request;String hashedCanonicalRequest Sign.sha256Hex(canonicalRequest.getBytes(StandardCharsets.UTF_8));String stringToSign TC3-HMAC-SHA256\n timestamp \n credentialScope \n hashedCanonicalRequest;String secretId this.credential.getSecretId();String secretKey this.credential.getSecretKey();byte[] secretDate Sign.hmac256((TC3 secretKey).getBytes(StandardCharsets.UTF_8), date);byte[] secretService Sign.hmac256(secretDate, service);byte[] secretSigning Sign.hmac256(secretService, tc3_request);String signature DatatypeConverter.printHexBinary(Sign.hmac256(secretSigning, stringToSign)).toLowerCase();return TC3-HMAC-SHA256 Credential secretId / credentialScope , SignedHeaders signedHeaders , Signature signature;}private String getResponseBody(String url, HashMapString, String headers, byte[] body)throws TencentCloudSDKException {Builder hb new Builder();for (String key : headers.keySet()) {hb.add(key, headers.get(key));}Response resp this.httpConnection.postRequest(url, body, hb.build());if (resp.code() ! AbstractClient.HTTP_RSP_OK) {String msg response code is resp.code() , not 200;log.info(msg);throw new TencentCloudSDKException(msg, , ServerSideError);}String respbody null;try {respbody resp.body().string();} catch (IOException e) {String msg Cannot transfer response body to string, because Content-Length is too large, or Content-Length and stream length disagree.;log.info(msg);throw new TencentCloudSDKException(msg, , e.getClass().getName());}JsonResponseModelJsonResponseErrModel errResp null;try {Type errType new TypeTokenJsonResponseModelJsonResponseErrModel() {}.getType();errResp gson.fromJson(respbody, errType);} catch (JsonSyntaxException e) {String msg json is not a valid representation for an object of type;log.info(msg);throw new TencentCloudSDKException(msg, , e.getClass().getName());}if (errResp.response.error ! null) {throw new TencentCloudSDKException(errResp.response.error.message, errResp.response.requestId, errResp.response.error.code);}return respbody;}private void trySetProxy(HttpConnection conn) {String host this.profile.getHttpProfile().getProxyHost();int port this.profile.getHttpProfile().getProxyPort();if (host null || host.isEmpty()) {return;}Proxy proxy new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));conn.setProxy(proxy);final String username this.profile.getHttpProfile().getProxyUsername();final String password this.profile.getHttpProfile().getProxyPassword();if (username null || username.isEmpty()) {return;}conn.setProxyAuthenticator(new Authenticator() {Overridepublic Request authenticate(Route route, Response response) throws IOException {String credential Credentials.basic(username, password);return response.request().newBuilder().header(Proxy-Authorization, credential).build();}});}protected String internalRequest(AbstractModel request, String actionName)throws TencentCloudSDKException {Response okRsp null;String endpoint this.getEndpoint();String[] binaryParams request.getBinaryParams();String sm this.profile.getSignMethod();String reqMethod this.profile.getHttpProfile().getReqMethod();// currently, customized params only can be supported via post json tc3-hmac-sha256HashMapString, Object customizedParams request.any();if (customizedParams.size() 0) {if (binaryParams.length 0) {throw new TencentCloudSDKException(WrongUsage: Cannot post multipart with customized parameters.);}if (sm.equals(ClientProfile.SIGN_SHA1) || sm.equals(ClientProfile.SIGN_SHA256)) {throw new TencentCloudSDKException(WrongUsage: Cannot use HmacSHA1 or HmacSHA256 with customized parameters.);}if (reqMethod.equals(HttpProfile.REQ_GET)) {throw new TencentCloudSDKException(WrongUsage: Cannot use get method with customized parameters.);}}if (binaryParams.length 0 || sm.equals(ClientProfile.SIGN_TC3_256)) {okRsp doRequestWithTC3(endpoint, request, actionName);} else if (sm.equals(ClientProfile.SIGN_SHA1) || sm.equals(ClientProfile.SIGN_SHA256)) {okRsp doRequest(endpoint, request, actionName);} else {throw new TencentCloudSDKException(Signature method sm is invalid or not supported yet.);}if (okRsp.code() ! AbstractClient.HTTP_RSP_OK) {String msg response code is okRsp.code() , not 200;log.info(msg);throw new TencentCloudSDKException(msg, , ServerSideError);}String strResp null;try {strResp okRsp.body().string();} catch (IOException e) {String msg Cannot transfer response body to string, because Content-Length is too large, or Content-Length and stream length disagree.;log.info(msg);throw new TencentCloudSDKException(msg, , endpoint.getClass().getName());}JsonResponseModelJsonResponseErrModel errResp null;try {Type errType new TypeTokenJsonResponseModelJsonResponseErrModel() {}.getType();errResp gson.fromJson(strResp, errType);} catch (JsonSyntaxException e) {String msg json is not a valid representation for an object of type;log.info(msg);throw new TencentCloudSDKException(msg, , e.getClass().getName());}if (errResp.response.error ! null) {throw new TencentCloudSDKException(errResp.response.error.message,errResp.response.requestId,errResp.response.error.code);}return strResp;}private Response doRequest(String endpoint, AbstractModel request, String action)throws TencentCloudSDKException {HashMapString, String param new HashMapString, String();request.toMap(param, );String strParam this.formatRequestData(action, param);String reqMethod this.profile.getHttpProfile().getReqMethod();String url REMOTE_SERVER_ADDRESS this.path;if (reqMethod.equals(HttpProfile.REQ_GET)) {return this.httpConnection.getRequest(url ? strParam);} else if (reqMethod.equals(HttpProfile.REQ_POST)) {return this.httpConnection.postRequest(url, strParam);} else {throw new TencentCloudSDKException(Method only support (GET, POST));}}private Response doRequestWithTC3(String endpoint, AbstractModel request, String action)throws TencentCloudSDKException {String httpRequestMethod this.profile.getHttpProfile().getReqMethod();if (httpRequestMethod null) {throw new TencentCloudSDKException(Request method should not be null, can only be GET or POST);}String contentType application/x-www-form-urlencoded;byte[] requestPayload .getBytes(StandardCharsets.UTF_8);HashMapString, String params new HashMapString, String();request.toMap(params, );String[] binaryParams request.getBinaryParams();if (binaryParams.length 0) {httpRequestMethod HttpProfile.REQ_POST;String boundary UUID.randomUUID().toString();// okhttp always set charset even we dont specify it,// to ensure signature be correct, we have to set it here as well.contentType multipart/form-data; charsetutf-8 ; boundary boundary;try {requestPayload getMultipartPayload(request, boundary);} catch (Exception e) {throw new TencentCloudSDKException(Failed to generate multipart. because: e);}} else if (httpRequestMethod.equals(HttpProfile.REQ_POST)) {requestPayload AbstractModel.toJsonString(request).getBytes(StandardCharsets.UTF_8);// okhttp always set charset even we dont specify it,// to ensure signature be correct, we have to set it here as well.contentType application/json; charsetutf-8;}String canonicalUri /;String canonicalQueryString this.getCanonicalQueryString(params, httpRequestMethod);String canonicalHeaders content-type: contentType \nhost: endpoint \n;String signedHeaders content-type;host;String hashedRequestPayload ;if (this.profile.isUnsignedPayload()) {hashedRequestPayload Sign.sha256Hex(UNSIGNED-PAYLOAD.getBytes(StandardCharsets.UTF_8));} else {hashedRequestPayload Sign.sha256Hex(requestPayload);}String canonicalRequest httpRequestMethod \n canonicalUri \n canonicalQueryString \n canonicalHeaders \n signedHeaders \n hashedRequestPayload;String timestamp String.valueOf(System.currentTimeMillis() / 1000);SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd);sdf.setTimeZone(TimeZone.getTimeZone(UTC));String date sdf.format(new Date(Long.valueOf(timestamp 000)));String service endpoint.split(\\.)[0];String credentialScope date / service / tc3_request;String hashedCanonicalRequest Sign.sha256Hex(canonicalRequest.getBytes(StandardCharsets.UTF_8));String stringToSign TC3-HMAC-SHA256\n timestamp \n credentialScope \n hashedCanonicalRequest;String secretId this.credential.getSecretId();String secretKey this.credential.getSecretKey();byte[] secretDate Sign.hmac256((TC3 secretKey).getBytes(StandardCharsets.UTF_8), date);byte[] secretService Sign.hmac256(secretDate, service);byte[] secretSigning Sign.hmac256(secretService, tc3_request);String signature DatatypeConverter.printHexBinary(Sign.hmac256(secretSigning, stringToSign)).toLowerCase();String authorization TC3-HMAC-SHA256 Credential secretId / credentialScope , SignedHeaders signedHeaders , Signature signature;String url REMOTE_SERVER_ADDRESS this.path;Builder hb new Builder();hb.add(Content-Type, contentType).add(Host, endpoint).add(Authorization, authorization).add(X-TC-Action, action).add(X-TC-Timestamp, timestamp).add(X-TC-Version, this.apiVersion).add(X-TC-RequestClient, SDK_VERSION);if (null ! this.getRegion()) {hb.add(X-TC-Region, this.getRegion());}String token this.credential.getToken();if (token ! null !token.isEmpty()) {hb.add(X-TC-Token, token);}if (this.profile.isUnsignedPayload()) {hb.add(X-TC-Content-SHA256, UNSIGNED-PAYLOAD);}if (null ! this.profile.getLanguage()) {hb.add(X-TC-Language, this.profile.getLanguage().getValue());}if (null ! service ) {hb.add(service, service);}if (null ! stringToSign ) {hb.add(stringToSign, new String(Base64.getEncoder().encode(stringToSign.getBytes())));}Headers headers hb.build();if (httpRequestMethod.equals(HttpProfile.REQ_GET)) {return this.httpConnection.getRequest(url ? canonicalQueryString, headers);} else if (httpRequestMethod.equals(HttpProfile.REQ_POST)) {return this.httpConnection.postRequest(url, requestPayload, headers);} else {throw new TencentCloudSDKException(Method only support GET, POST);}}private byte[] getMultipartPayload(AbstractModel request, String boundary) throws Exception {ByteArrayOutputStream baos new ByteArrayOutputStream();String[] binaryParams request.getBinaryParams();for (Map.EntryString, byte[] entry : request.getMultipartRequestParams().entrySet()) {baos.write(--.getBytes(StandardCharsets.UTF_8));baos.write(boundary.getBytes(StandardCharsets.UTF_8));baos.write(\r\n.getBytes(StandardCharsets.UTF_8));baos.write(Content-Disposition: form-data; name\.getBytes(StandardCharsets.UTF_8));baos.write(entry.getKey().getBytes(StandardCharsets.UTF_8));if (Arrays.asList(binaryParams).contains(entry.getKey())) {baos.write(\; filename\.getBytes(StandardCharsets.UTF_8));baos.write(entry.getKey().getBytes(StandardCharsets.UTF_8));baos.write(\\r\n.getBytes(StandardCharsets.UTF_8));} else {baos.write(\\r\n.getBytes(StandardCharsets.UTF_8));}baos.write(\r\n.getBytes(StandardCharsets.UTF_8));baos.write(entry.getValue());baos.write(\r\n.getBytes(StandardCharsets.UTF_8));}if (baos.size() ! 0) {baos.write(--.getBytes(StandardCharsets.UTF_8));baos.write(boundary.getBytes(StandardCharsets.UTF_8));baos.write(--\r\n.getBytes(StandardCharsets.UTF_8));}byte[] bytes baos.toByteArray();baos.close();return bytes;}private String getCanonicalQueryString(HashMapString, String params, String method)throws TencentCloudSDKException {if (method ! null method.equals(HttpProfile.REQ_POST)) {return ;}StringBuilder queryString new StringBuilder();for (Map.EntryString, String entry : params.entrySet()) {String v;try {v URLEncoder.encode(entry.getValue(), UTF8);} catch (UnsupportedEncodingException e) {throw new TencentCloudSDKException(UTF8 is not supported. e.getMessage());}queryString.append().append(entry.getKey()).append().append(v);}if (queryString.length() 0) {return ;} else {return queryString.toString().substring(1);}}private String formatRequestData(String action, MapString, String param)throws TencentCloudSDKException {param.put(Action, action);param.put(RequestClient, this.sdkVersion);param.put(Nonce, String.valueOf(Math.abs(new SecureRandom().nextInt())));param.put(Timestamp, String.valueOf(System.currentTimeMillis() / 1000));param.put(Version, this.apiVersion);if (this.credential.getSecretId() ! null (!this.credential.getSecretId().isEmpty())) {param.put(SecretId, this.credential.getSecretId());}if (this.region ! null (!this.region.isEmpty())) {param.put(Region, this.region);}if (this.profile.getSignMethod() ! null (!this.profile.getSignMethod().isEmpty())) {param.put(SignatureMethod, this.profile.getSignMethod());}if (this.credential.getToken() ! null (!this.credential.getToken().isEmpty())) {param.put(Token, this.credential.getToken());}if (null ! this.profile.getLanguage()) {param.put(Language, this.profile.getLanguage().getValue());}String endpoint this.getEndpoint();String sigInParam Sign.makeSignPlainText(new TreeMapString, String(param),this.profile.getHttpProfile().getReqMethod(),endpoint,this.path);String sigOutParam Sign.sign(this.credential.getSecretKey(), sigInParam, this.profile.getSignMethod());String strParam ;try {for (Map.EntryString, String entry : param.entrySet()) {strParam (URLEncoder.encode(entry.getKey(), utf-8) URLEncoder.encode(entry.getValue(), utf-8) );}strParam (Signature URLEncoder.encode(sigOutParam, utf-8));} catch (UnsupportedEncodingException e) {throw new TencentCloudSDKException(e.getClass().getName() - e.getMessage());}return strParam;}/** warm up, try to avoid unnecessary cost in the first request */private void warmup() {try {// it happens in SDK signature process.// first invoke costs around 250 ms.Mac.getInstance(HmacSHA1);Mac.getInstance(HmacSHA256);// it happens inside okhttp, but I think any https framework/package will do the same.// first invoke costs around 150 ms.SSLContext sslContext SSLContext.getInstance(TLS);sslContext.init(null, null, null);} catch (Exception e) {// ignore but print message to consolee.printStackTrace();}}private String getEndpoint() {// in case user has reset endpoint after init this clientif (null ! this.profile.getHttpProfile().getEndpoint()) {return this.profile.getHttpProfile().getEndpoint();} else {// protected abstract String getService();// use this.getService() from overrided subclass will be betterreturn this.service . this.profile.getHttpProfile().getRootDomain();}}/*** 请注意购买类接口谨慎调用可能导致多次购买* 仅幂等接口推荐使用** param req* param retryTimes* throws TencentCloudSDKException*/public Object retry(AbstractModel req, int retryTimes) throws TencentCloudSDKException {if (retryTimes 0 || retryTimes 10) {throw new TencentCloudSDKException(The number of retryTimes supported is 0 to 10., , ClientSideError);}Class cls this.getClass();String methodName req.getClass().getSimpleName().replace(Request, );Method method;try {method cls.getMethod(methodName, req.getClass());} catch (NoSuchMethodException e) {throw new TencentCloudSDKException(e.toString(), , ClientSideError);}do {try {return method.invoke(this, req);} catch (IllegalAccessException e) {throw new TencentCloudSDKException(e.toString(), , ClientSideError);} catch (InvocationTargetException e) {if (retryTimes 0) {throw (TencentCloudSDKException) e.getTargetException();}}try {Thread.sleep(1000);} catch (InterruptedException e) {throw new TencentCloudSDKException(e.toString(), , ClientSideError);}} while (--retryTimes 0);return null;} }将源码中上述类修改后重新达成jar包即可。 本人近十年JAVA架构设计经验长期从事IT技术资源整合。有志于自我技术提升、需要最新IT技术课程的小伙伴可私信联系我 粉丝一律白菜价
http://www.tj-hxxt.cn/news/143448.html

相关文章:

  • icp备案单位网站白度
  • 网站怎么访问自己做的网页安装wordpress主题失败
  • 足球竞猜网站开发重庆家居网站制作公司
  • 贵州建网站的公司网站的建设论文
  • 在某网站被骗钱该怎么做上海关键词优化的技巧
  • 做服装必须看的十大网站本地的上海网站建设
  • 中职示范校建设专题网站长尾关键词排名系统
  • 揭阳网站制作软件南昌做seo的公司
  • 公司网站建设文案五大跨境电商平台对比分析
  • 网站模板设计举例创办网站要多少钱
  • 永康企业网站建设公司门户网站建设服务报价
  • 公明网站建设怎么做wordpress 图片路径加密
  • 娱乐建设网站公司网站制作费用申请
  • 织梦手机网站制作在哪可以建一个网站
  • 怎么看网站有没有做301跳转小小影院免费高清电视剧
  • 有做网站代理运营的吗番禺人才网单位招考
  • 东莞 网站建设企业南通优普企业网站建设
  • 响应式网站建设的好处珠海网页设计公司
  • 网站怎么做等级保护母婴的网站建设
  • 南通做网站的公司有哪些绍兴柯桥建设局网站
  • 网站开发设计的步骤电子商务网站建设公
  • 定制摄影app和摄影网站的区别网站建设速度如何解决
  • 做国外购物网站长沙企业网站开发
  • 特色专业建设网站ps 怎么做网站搜索框
  • 虚拟主机上的网站上传方式网站设计方案应该怎么做
  • 企业网站手机端wordpress 登陆可见
  • 做足球网站前景怎样用自己的pid做搜索网站
  • 网站建设分几块wordpress分类名称
  • 企业网站建设建议萍乡招聘网站建设
  • 微商城网站建设市场wordpress 图片选择器