mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	优化华为短信客户端实现,去除两个新增类HuaweiRequest、HuaweiSigner
This commit is contained in:
		| @@ -2,16 +2,17 @@ package cn.iocoder.yudao.module.system.framework.sms.core.client.impl; | |||||||
|  |  | ||||||
|  |  | ||||||
| import cn.hutool.core.lang.Assert; | import cn.hutool.core.lang.Assert; | ||||||
|  | import cn.hutool.core.util.HexUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
|  |  | ||||||
|  | import cn.hutool.crypto.SecureUtil; | ||||||
|  | import cn.hutool.crypto.digest.DigestUtil; | ||||||
| import cn.hutool.json.JSONArray; | import cn.hutool.json.JSONArray; | ||||||
| import cn.iocoder.yudao.framework.common.core.KeyValue; | import cn.iocoder.yudao.framework.common.core.KeyValue; | ||||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||||
| import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO; | import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO; | ||||||
| import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO; | import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO; | ||||||
| import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO; | import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO; | ||||||
| import cn.iocoder.yudao.module.system.framework.sms.core.client.utils.HuaweiRequest; |  | ||||||
| import cn.iocoder.yudao.module.system.framework.sms.core.client.utils.HuaweiSigner; |  | ||||||
| import cn.iocoder.yudao.module.system.framework.sms.core.enums.SmsTemplateAuditStatusEnum; | import cn.iocoder.yudao.module.system.framework.sms.core.enums.SmsTemplateAuditStatusEnum; | ||||||
| import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties; | import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties; | ||||||
| import org.apache.http.client.methods.*; | import org.apache.http.client.methods.*; | ||||||
| @@ -30,6 +31,7 @@ import org.apache.http.HttpResponse; | |||||||
| import java.io.UnsupportedEncodingException; | import java.io.UnsupportedEncodingException; | ||||||
| import java.net.URLEncoder; | import java.net.URLEncoder; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
| import java.util.*; | import java.util.*; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -55,6 +57,7 @@ public class HuaweiSmsClient extends AbstractSmsClient { | |||||||
|      */ |      */ | ||||||
|     public static final String API_CODE_SUCCESS = "OK"; |     public static final String API_CODE_SUCCESS = "OK"; | ||||||
|     private static final Logger LOGGER = LoggerFactory.getLogger(HuaweiSmsClient.class); |     private static final Logger LOGGER = LoggerFactory.getLogger(HuaweiSmsClient.class); | ||||||
|  |  | ||||||
|     public HuaweiSmsClient(SmsChannelProperties properties) { |     public HuaweiSmsClient(SmsChannelProperties properties) { | ||||||
|         super(properties); |         super(properties); | ||||||
|         Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空"); |         Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空"); | ||||||
| @@ -79,6 +82,18 @@ public class HuaweiSmsClient extends AbstractSmsClient { | |||||||
|         //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 |         //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 | ||||||
|         String statusCallBack = properties.getCallbackUrl(); |         String statusCallBack = properties.getCallbackUrl(); | ||||||
|  |  | ||||||
|  |         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.ENGLISH); | ||||||
|  |         sdf.setTimeZone(TimeZone.getTimeZone("UTC")); | ||||||
|  |         String singerDate = sdf.format(new Date()); | ||||||
|  |  | ||||||
|  |         // ************* 步骤 1:拼接规范请求串 ************* | ||||||
|  |         String httpRequestMethod = "POST"; | ||||||
|  |         String canonicalUri = "/sms/batchSendSms/v1/"; | ||||||
|  |         String canonicalQueryString = "";//查询参数为空 | ||||||
|  |         String canonicalHeaders = "content-type:application/x-www-form-urlencoded\n" | ||||||
|  |                 + "host:smsapi.cn-north-4.myhuaweicloud.com:443\n" | ||||||
|  |                 + "x-sdk-date:" + singerDate + "\n"; | ||||||
|  |         String signedHeaders = "content-type;host;x-sdk-date"; | ||||||
|         /** |         /** | ||||||
|          * 选填,使用无变量模板时请赋空值 String templateParas = ""; |          * 选填,使用无变量模板时请赋空值 String templateParas = ""; | ||||||
|          * 单变量模板示例:模板内容为"您的验证码是${NUM_6}"时,templateParas可填写为"[\"111111\"]" |          * 单变量模板示例:模板内容为"您的验证码是${NUM_6}"时,templateParas可填写为"[\"111111\"]" | ||||||
| @@ -92,31 +107,34 @@ public class HuaweiSmsClient extends AbstractSmsClient { | |||||||
|         //请求Body,不携带签名名称时,signature请填null |         //请求Body,不携带签名名称时,signature请填null | ||||||
|         String body = buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, null); |         String body = buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, null); | ||||||
|         if (null == body || body.isEmpty()) { |         if (null == body || body.isEmpty()) { | ||||||
|             LOGGER.warn("body is null."); |  | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|  |         String hashedRequestBody = HexUtil.encodeHexStr(DigestUtil.sha256(body)); | ||||||
|  |         String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" | ||||||
|  |                 + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestBody; | ||||||
|  |  | ||||||
|         HuaweiRequest request = new HuaweiRequest(); |         // ************* 步骤 2:拼接待签名字符串 ************* | ||||||
|         request.setKey(properties.getApiKey()); |         String hashedCanonicalRequest = HexUtil.encodeHexStr(DigestUtil.sha256(canonicalRequest)); | ||||||
|         request.setSecret(properties.getApiSecret()); |         String stringToSign = "SDK-HMAC-SHA256" + "\n" + singerDate + "\n" + hashedCanonicalRequest; | ||||||
|         request.setMethod("POST"); |  | ||||||
|         request.setUrl(url); |  | ||||||
|         request.addHeader("Content-Type", "application/x-www-form-urlencoded"); |  | ||||||
|         request.setBody(body); |  | ||||||
|         LOGGER.info("Print the body: {}", body); |  | ||||||
|  |  | ||||||
|         HuaweiSigner signer = new HuaweiSigner("SDK-HMAC-SHA256"); |         // ************* 步骤 3:计算签名 ************* | ||||||
|         signer.sign(request); |         String signature = SecureUtil.hmacSha256(properties.getApiSecret()).digestHex(stringToSign); | ||||||
|  |  | ||||||
|  |         // ************* 步骤 4:拼接 Authorization ************* | ||||||
|  |         String authorization = "SDK-HMAC-SHA256" + " " + "Access=" + properties.getApiKey() + ", " | ||||||
|  |                 + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature; | ||||||
|  |  | ||||||
|  |         // ************* 步骤 5:构造HttpRequest 并执行request请求,获得response ************* | ||||||
|         HttpUriRequest postMethod = RequestBuilder.post() |         HttpUriRequest postMethod = RequestBuilder.post() | ||||||
|                 .setUri(url) |                 .setUri(url) | ||||||
|                 .setEntity(new StringEntity(request.getBody(), StandardCharsets.UTF_8)) |                 .setEntity(new StringEntity(body, StandardCharsets.UTF_8)) | ||||||
|                 .setHeader("Content-Type","application/x-www-form-urlencoded") |                 .setHeader("Content-Type","application/x-www-form-urlencoded") | ||||||
|                 .setHeader("X-Sdk-Date",request.getHeaders().get("X-Sdk-Date")) |                 .setHeader("X-Sdk-Date",singerDate) | ||||||
|                 .setHeader("Authorization",request.getHeaders().get("Authorization")) |                 .setHeader("Authorization",authorization) | ||||||
|                 .build(); |                 .build(); | ||||||
|         CloseableHttpClient client = HttpClientBuilder.create().build(); |         CloseableHttpClient client = HttpClientBuilder.create().build(); | ||||||
|  |  | ||||||
|         HttpResponse response = client.execute(postMethod); |         HttpResponse response = client.execute(postMethod); | ||||||
|  |  | ||||||
|         return new SmsSendRespDTO().setSuccess(Objects.equals(response.getStatusLine().getReasonPhrase(), API_CODE_SUCCESS)).setSerialNo(Integer.toString(response.getStatusLine().getStatusCode())) |         return new SmsSendRespDTO().setSuccess(Objects.equals(response.getStatusLine().getReasonPhrase(), API_CODE_SUCCESS)).setSerialNo(Integer.toString(response.getStatusLine().getStatusCode())) | ||||||
|                 .setApiRequestId(null).setApiCode(null).setApiMsg(null); |                 .setApiRequestId(null).setApiCode(null).setApiMsg(null); | ||||||
|     } |     } | ||||||
| @@ -141,7 +159,6 @@ public class HuaweiSmsClient extends AbstractSmsClient { | |||||||
|  |  | ||||||
|     private static void appendToBody(StringBuilder body, String key, String val) throws UnsupportedEncodingException { |     private static void appendToBody(StringBuilder body, String key, String val) throws UnsupportedEncodingException { | ||||||
|         if (null != val && !val.isEmpty()) { |         if (null != val && !val.isEmpty()) { | ||||||
|             LOGGER.info("Print appendToBody: {}:{}", key, val); |  | ||||||
|             body.append(key).append(URLEncoder.encode(val, "UTF-8")); |             body.append(key).append(URLEncoder.encode(val, "UTF-8")); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -181,20 +198,17 @@ public class HuaweiSmsClient extends AbstractSmsClient { | |||||||
|         /** |         /** | ||||||
|          * 短信资源的更新时间,通常为短信平台接收短信状态报告的时间 |          * 短信资源的更新时间,通常为短信平台接收短信状态报告的时间 | ||||||
|          */ |          */ | ||||||
|         @JsonProperty("updateTime") |  | ||||||
|         @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) |         @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) | ||||||
|         private LocalDateTime updateTime; |         private LocalDateTime updateTime; | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * 短信状态报告枚举值 |          * 短信状态报告枚举值 | ||||||
|          */ |          */ | ||||||
|         @JsonProperty("status") |  | ||||||
|         private String status; |         private String status; | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * 发送短信成功时返回的短信唯一标识。 |          * 发送短信成功时返回的短信唯一标识。 | ||||||
|          */ |          */ | ||||||
|         @JsonProperty("smsMsgId") |  | ||||||
|         private String smsMsgId; |         private String smsMsgId; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 scholar
					scholar