Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
amos-boot-biz
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
项目统一框架
amos-boot-biz
Commits
90094e42
Commit
90094e42
authored
Jul 12, 2023
by
xixinzhao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
集成华为短信平台
parent
371b04a6
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
312 additions
and
11 deletions
+312
-11
HwSendSms.java
...om/yeejoin/amos/boot/module/hygf/api/hwsms/HwSendSms.java
+258
-0
SendSmsCode.java
.../yeejoin/amos/boot/module/hygf/api/hwsms/SendSmsCode.java
+26
-0
UnitInfoController.java
...s/boot/module/hygf/biz/controller/UnitInfoController.java
+16
-11
application-dev.properties
...le-hygf-biz/src/main/resources/application-dev.properties
+12
-0
No files found.
amos-boot-system-jxiop/amos-boot-module-hygf-api/src/main/java/com/yeejoin/amos/boot/module/hygf/api/hwsms/HwSendSms.java
0 → 100644
View file @
90094e42
package
com
.
yeejoin
.
amos
.
boot
.
module
.
hygf
.
api
.
hwsms
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
javax.net.ssl.*
;
import
java.io.*
;
import
java.net.URL
;
import
java.net.URLEncoder
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
/**
*
* @author DELL
*/
@Component
@Slf4j
public
class
HwSendSms
{
/**
* 无需修改,用于格式化鉴权头域,给"X-WSSE"参数赋值
*/
private
static
final
String
WSSE_HEADER_FORMAT
=
"UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\""
;
/**
* 无需修改,用于格式化鉴权头域,给"Authorization"参数赋值
*/
private
static
final
String
AUTH_HEADER_VALUE
=
"WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\""
;
private
static
final
String
UTF_8
=
"UTF-8"
;
private
static
final
int
SUCCESS_STATUS
=
200
;
private
static
final
int
FAIL_STATUS
=
500
;
@Value
(
"${sms.huawei.url}"
)
private
String
url
;
@Value
(
"${sms.huawei.appKey}"
)
private
String
appKey
;
@Value
(
"${sms.huawei.appSecret}"
)
private
String
appSecret
;
@Value
(
"${sms.huawei.sender}"
)
private
String
sender
;
@Value
(
"${sms.huawei.signature}"
)
private
String
signature
;
public
int
sendSms
(
String
receiver
,
String
templateParas
,
String
templateId
)
throws
Exception
{
//选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
String
statusCallBack
=
""
;
/**
* 选填,使用无变量模板时请赋空值 String templateParas = "";
* 单变量模板示例:模板内容为"您的验证码是${1}"时,templateParas可填写为"[\"369751\"]"
* 双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,templateParas可填写为"[\"3\",\"人民公园正门\"]"
* 模板中的每个变量都必须赋值,且取值不能为空
* 查看更多模板和变量规范:产品介绍>模板和变量规范
*/
//模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。
// String templateParas = "[\"12345\"]";
//请求Body,不携带签名名称时,signature请填null
String
body
=
buildRequestBody
(
sender
,
receiver
,
templateId
,
templateParas
,
statusCallBack
,
signature
);
if
(
null
==
body
||
body
.
isEmpty
())
{
log
.
info
(
"body is null."
);
return
FAIL_STATUS
;
}
//请求Headers中的X-WSSE参数值
String
wsseHeader
=
buildWsseHeader
(
appKey
,
appSecret
);
if
(
null
==
wsseHeader
||
wsseHeader
.
isEmpty
())
{
log
.
info
(
"wsse header is null."
);
return
FAIL_STATUS
;
}
Writer
out
=
null
;
BufferedReader
in
=
null
;
StringBuffer
result
=
new
StringBuffer
();
HttpsURLConnection
connection
=
null
;
InputStream
is
=
null
;
//为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
HostnameVerifier
hv
=
new
HostnameVerifier
()
{
@Override
public
boolean
verify
(
String
hostname
,
SSLSession
session
)
{
return
true
;
}
};
trustAllHttpsCertificates
();
try
{
URL
realUrl
=
new
URL
(
url
);
connection
=
(
HttpsURLConnection
)
realUrl
.
openConnection
();
connection
.
setHostnameVerifier
(
hv
);
connection
.
setDoOutput
(
true
);
connection
.
setDoInput
(
true
);
connection
.
setUseCaches
(
true
);
//请求方法
connection
.
setRequestMethod
(
"POST"
);
//请求Headers参数
connection
.
setRequestProperty
(
"Content-Type"
,
"application/x-www-form-urlencoded"
);
connection
.
setRequestProperty
(
"Authorization"
,
AUTH_HEADER_VALUE
);
connection
.
setRequestProperty
(
"X-WSSE"
,
wsseHeader
);
connection
.
connect
();
out
=
new
OutputStreamWriter
(
connection
.
getOutputStream
());
//发送请求Body参数
out
.
write
(
body
);
out
.
flush
();
out
.
close
();
int
status
=
connection
.
getResponseCode
();
if
(
SUCCESS_STATUS
==
status
)
{
is
=
connection
.
getInputStream
();
}
else
{
//400/401
is
=
connection
.
getErrorStream
();
}
in
=
new
BufferedReader
(
new
InputStreamReader
(
is
,
UTF_8
));
String
line
=
""
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
result
.
append
(
line
);
}
log
.
info
(
"短信发送返回详情:{}"
,
result
.
toString
());
return
status
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
FAIL_STATUS
;
}
finally
{
try
{
if
(
null
!=
out
)
{
out
.
close
();
}
if
(
null
!=
is
)
{
is
.
close
();
}
if
(
null
!=
in
)
{
in
.
close
();
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
/**
* 构造请求Body体
* @param sender
* @param receiver
* @param templateId
* @param templateParas
* @param statusCallBack
* @param signature | 签名名称,使用中国大陆短信通用模板时填写
* @return
*/
static
String
buildRequestBody
(
String
sender
,
String
receiver
,
String
templateId
,
String
templateParas
,
String
statusCallBack
,
String
signature
)
{
if
(
null
==
sender
||
null
==
receiver
||
null
==
templateId
||
sender
.
isEmpty
()
||
receiver
.
isEmpty
()
||
templateId
.
isEmpty
())
{
System
.
out
.
println
(
"buildRequestBody(): sender, receiver or templateId is null."
);
return
null
;
}
Map
<
String
,
String
>
map
=
new
HashMap
<
String
,
String
>();
map
.
put
(
"from"
,
sender
);
map
.
put
(
"to"
,
receiver
);
map
.
put
(
"templateId"
,
templateId
);
if
(
null
!=
templateParas
&&
!
templateParas
.
isEmpty
())
{
map
.
put
(
"templateParas"
,
templateParas
);
}
if
(
null
!=
statusCallBack
&&
!
statusCallBack
.
isEmpty
())
{
map
.
put
(
"statusCallback"
,
statusCallBack
);
}
if
(
null
!=
signature
&&
!
signature
.
isEmpty
())
{
map
.
put
(
"signature"
,
signature
);
}
StringBuilder
sb
=
new
StringBuilder
();
String
temp
=
""
;
for
(
String
s
:
map
.
keySet
())
{
try
{
temp
=
URLEncoder
.
encode
(
map
.
get
(
s
),
"UTF-8"
);
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
sb
.
append
(
s
).
append
(
"="
).
append
(
temp
).
append
(
"&"
);
}
return
sb
.
deleteCharAt
(
sb
.
length
()-
1
).
toString
();
}
/**
* 构造X-WSSE参数值
* @param appKey
* @param appSecret
* @return
*/
static
String
buildWsseHeader
(
String
appKey
,
String
appSecret
)
{
if
(
null
==
appKey
||
null
==
appSecret
||
appKey
.
isEmpty
()
||
appSecret
.
isEmpty
())
{
System
.
out
.
println
(
"buildWsseHeader(): appKey or appSecret is null."
);
return
null
;
}
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyy-MM-dd'T'HH:mm:ss'Z'"
);
String
time
=
sdf
.
format
(
new
Date
());
//Created
String
nonce
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
//Nonce
MessageDigest
md
;
byte
[]
passwordDigest
=
null
;
try
{
md
=
MessageDigest
.
getInstance
(
"SHA-256"
);
md
.
update
((
nonce
+
time
+
appSecret
).
getBytes
());
passwordDigest
=
md
.
digest
();
}
catch
(
NoSuchAlgorithmException
e
)
{
e
.
printStackTrace
();
}
//如果JDK版本是1.8,请加载原生Base64类,并使用如下代码
String
passwordDigestBase64Str
=
Base64
.
getEncoder
().
encodeToString
(
passwordDigest
);
//PasswordDigest
//如果JDK版本低于1.8,请加载三方库提供Base64类,并使用如下代码
//String passwordDigestBase64Str = Base64.encodeBase64String(passwordDigest); //PasswordDigest
//若passwordDigestBase64Str中包含换行符,请执行如下代码进行修正
//passwordDigestBase64Str = passwordDigestBase64Str.replaceAll("[\\s*\t\n\r]", "");
return
String
.
format
(
WSSE_HEADER_FORMAT
,
appKey
,
passwordDigestBase64Str
,
nonce
,
time
);
}
/**
* 忽略证书信任问题
* @throws Exception
*/
static
void
trustAllHttpsCertificates
()
throws
Exception
{
TrustManager
[]
trustAllCerts
=
new
TrustManager
[]
{
new
X509TrustManager
()
{
public
void
checkClientTrusted
(
X509Certificate
[]
chain
,
String
authType
)
throws
CertificateException
{
return
;
}
public
void
checkServerTrusted
(
X509Certificate
[]
chain
,
String
authType
)
throws
CertificateException
{
return
;
}
public
X509Certificate
[]
getAcceptedIssuers
()
{
return
null
;
}
}
};
SSLContext
sc
=
SSLContext
.
getInstance
(
"SSL"
);
sc
.
init
(
null
,
trustAllCerts
,
null
);
HttpsURLConnection
.
setDefaultSSLSocketFactory
(
sc
.
getSocketFactory
());
}
}
amos-boot-system-jxiop/amos-boot-module-hygf-api/src/main/java/com/yeejoin/amos/boot/module/hygf/api/hwsms/SendSmsCode.java
0 → 100644
View file @
90094e42
package
com
.
yeejoin
.
amos
.
boot
.
module
.
hygf
.
api
.
hwsms
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
/**
* 发送短信验证码
* @author xxz
*/
@Component
public
class
SendSmsCode
{
@Autowired
HwSendSms
hwSendSms
;
@Value
(
"${sms.huawei.templateId}"
)
private
String
templateId
;
private
static
final
int
SUCCESS_STATUS
=
200
;
public
boolean
sendSmsCode
(
String
mobile
,
String
templateParas
)
throws
Exception
{
int
i
=
hwSendSms
.
sendSms
(
mobile
,
templateParas
,
templateId
);
return
i
==
SUCCESS_STATUS
;
}
}
amos-boot-system-jxiop/amos-boot-module-hygf-biz/src/main/java/com/yeejoin/amos/boot/module/hygf/biz/controller/UnitInfoController.java
View file @
90094e42
package
com
.
yeejoin
.
amos
.
boot
.
module
.
hygf
.
biz
.
controller
;
import
com.yeejoin.amos.boot.biz.common.utils.RedisKey
;
import
com.yeejoin.amos.boot.biz.common.utils.RedisUtils
;
import
com.yeejoin.amos.boot.module.common.biz.utils.CommonResponseUtil
;
import
com.yeejoin.amos.boot.module.hygf.api.dto.UnitRegisterDto
;
import
com.yeejoin.amos.boot.module.
ugp.api.constants.XJConstant
;
import
com.yeejoin.amos.boot.module.
hygf.api.hwsms.SendSmsCode
;
import
com.yeejoin.amos.component.feign.model.FeignClientResult
;
import
com.yeejoin.amos.component.robot.AmosRequestContext
;
import
com.yeejoin.amos.feign.privilege.Privilege
;
import
com.yeejoin.amos.feign.systemctl.Systemctl
;
import
com.yeejoin.amos.feign.systemctl.model.RegionModel
;
import
io.swagger.annotations.ApiParam
;
import
org.apache.
commons.lang3.ObjectUtils
;
import
org.apache.
poi.util.ArrayUtil
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.web.bind.annotation.RequestMapping
;
...
...
@@ -62,12 +61,15 @@ public class UnitInfoController extends BaseController {
@Value
(
"${hygf.sms.tempCode}"
)
private
String
smsTempCode
;
@Autowired
SendSmsCode
sendSmsCode
;
public
static
final
String
HYGF_USER_TEL
=
"hygf_tel_"
;
/**
* 验证码过期时间
*/
private
long
time
=
600
l
;
private
long
time
=
180L
;
/**
* 根据sequenceNbr更新
...
...
@@ -239,25 +241,28 @@ public class UnitInfoController extends BaseController {
@TycloudOperation
(
needAuth
=
false
,
ApiLevel
=
UserType
.
AGENCY
)
@GetMapping
(
value
=
"/sendTelCode/{tel}"
)
@ApiOperation
(
httpMethod
=
"GET"
,
value
=
"发送手机号验证码"
,
notes
=
"发送手机号验证码"
)
public
ResponseModel
<
Boolean
>
sendTelCode
(
@PathVariable
(
value
=
"tel"
)
String
tel
,
public
ResponseModel
<
Boolean
>
sendTelCode
(
@PathVariable
(
value
=
"tel"
)
String
tel
,
@RequestParam
(
value
=
"type"
,
required
=
false
)
String
type
)
{
if
(
ValidationUtil
.
isEmpty
(
tel
))
{
throw
new
BadRequest
(
"参数校验失败."
);
}
Boolean
flag
=
fals
e
;
HashMap
<
String
,
String
>
params
=
new
HashMap
<>();
Boolean
flag
=
tru
e
;
HashMap
<
String
,
String
>
params
=
new
HashMap
<>(
3
);
String
code
=
this
.
getRandomCode
();
params
.
put
(
"code"
,
code
);
params
.
put
(
"mobile"
,
tel
);
params
.
put
(
"smsCode"
,
smsTempCode
);
try
{
Systemctl
.
smsClient
.
sendCommonSms
(
params
).
getResult
();
flag
=
true
;
String
[]
templateParas
=
{
code
};
String
s
=
Arrays
.
toString
(
templateParas
);
sendSmsCode
.
sendSmsCode
(
tel
,
s
);
// Systemctl.smsClient.sendCommonSms(params).getResult();
// code 保存到缓存中
redisUtil
.
set
(
HYGF_USER_TEL
+
tel
,
code
,
time
);
}
catch
(
Exception
e
)
{
throw
new
BadRequest
(
"发送短信失败:"
+
e
.
getMessage
());
}
// code 保存到缓存中
redisUtil
.
set
(
HYGF_USER_TEL
+
tel
,
code
,
time
);
return
ResponseHelper
.
buildResponse
(
flag
);
}
...
...
amos-boot-system-jxiop/amos-boot-module-hygf-biz/src/main/resources/application-dev.properties
View file @
90094e42
...
...
@@ -91,3 +91,14 @@ regulator.unit.code=86*258
dealer.appcode
=
studio_normalapp_5133538
hygf.sms.tempCode
=
SMS_TZS_0001
# 华为短信相关配置
sms.huawei.url
=
https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1
sms.huawei.appKey
=
n3FYPWO7Heo1ze212QRBvF4VA2E2
sms.huawei.appSecret
=
IFhiMpWROi7w4Ei21ZbfIjKyt97b
# 模板id
sms.huawei.templateId
=
6aaeb4bf916d4db0a1942c598912519e
# 签名通道号
sms.huawei.sender
=
1069368924410006092
# 签名名称
sms.huawei.signature
=
华为云短信测试
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment