Compare commits
3 Commits
da382b3255
...
ca8aaa0e2d
| Author | SHA1 | Date |
|---|---|---|
|
|
ca8aaa0e2d | 1 week ago |
|
|
7e93baf379 | 1 week ago |
|
|
533fcaa2bd | 1 week ago |
6 changed files with 320 additions and 27 deletions
@ -0,0 +1,149 @@ |
|||||
|
package com.zdxt.enforcementcode.common.util; |
||||
|
|
||||
|
import java.security.MessageDigest; |
||||
|
import java.util.Base64; |
||||
|
|
||||
|
/** |
||||
|
* Azdg加密工具类 |
||||
|
* |
||||
|
* @author longshangbo@163.com |
||||
|
* |
||||
|
* <p>2019年11月18日 下午5:36:14</p> |
||||
|
*/ |
||||
|
public class Azdg { |
||||
|
|
||||
|
private static final String key = "chinagdn"; |
||||
|
|
||||
|
private static final Azdg INSTANCE = new Azdg(); |
||||
|
|
||||
|
/** |
||||
|
* 解密 |
||||
|
* @param cipherText 要解密的内容 |
||||
|
* @return 解密后的字符串 |
||||
|
*/ |
||||
|
public static String decrypt(String cipherText) { |
||||
|
return INSTANCE.decrypt(cipherText, key); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 加密 |
||||
|
* @param txt 要加密的内容 |
||||
|
* @return 加密后的字符串 |
||||
|
*/ |
||||
|
public static String encrypt(String txt) { |
||||
|
return INSTANCE.encrypt(txt, key); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 加密 |
||||
|
* @param txt |
||||
|
* @param key |
||||
|
* @return |
||||
|
*/ |
||||
|
public String encrypt(String txt, String key) { |
||||
|
|
||||
|
String encrypt_key = "0f9cfb7a9acced8a4167ea8006ccd098"; |
||||
|
int ctr = 0; |
||||
|
String tmp = ""; |
||||
|
int i; |
||||
|
|
||||
|
for (i = 0; i < txt.length(); i++) { |
||||
|
ctr = (ctr == encrypt_key.length()) ? 0 : ctr; |
||||
|
tmp = tmp + encrypt_key.charAt(ctr) + (char) (txt.charAt(i) ^ encrypt_key.charAt(ctr)); |
||||
|
ctr++; |
||||
|
} |
||||
|
|
||||
|
return base64_encode(key(tmp, key)); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 解密 |
||||
|
* @param cipherText |
||||
|
* @param key |
||||
|
* @return |
||||
|
*/ |
||||
|
public String decrypt(String cipherText, String key) { |
||||
|
|
||||
|
// base64解码
|
||||
|
cipherText = base64_decode(cipherText); |
||||
|
cipherText = key(cipherText, key); |
||||
|
String tmp = ""; |
||||
|
|
||||
|
for (int i = 0; i < cipherText.length(); i++) { |
||||
|
int c = cipherText.charAt(i) ^ cipherText.charAt(i + 1); |
||||
|
String x = "" + (char) c; |
||||
|
tmp += x; |
||||
|
i++; |
||||
|
} |
||||
|
return tmp; |
||||
|
} |
||||
|
|
||||
|
public String base64_decode(String str) { |
||||
|
|
||||
|
// sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
|
||||
|
|
||||
|
if (str == null) |
||||
|
return null; |
||||
|
return new String(Base64.getDecoder().decode(str)); |
||||
|
} |
||||
|
|
||||
|
public String key(String txt, String encrypt_key) { |
||||
|
|
||||
|
encrypt_key = strMD5(encrypt_key); |
||||
|
int ctr = 0; |
||||
|
String tmp = ""; |
||||
|
|
||||
|
for (int i = 0; i < txt.length(); i++) { |
||||
|
|
||||
|
ctr = (ctr == encrypt_key.length()) ? 0 : ctr; |
||||
|
int c = txt.charAt(i) ^ encrypt_key.charAt(ctr); |
||||
|
String x = "" + (char) c; |
||||
|
tmp = tmp + x; |
||||
|
ctr++; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return tmp; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public String base64_encode(String str) { |
||||
|
if (str == null) |
||||
|
return null; |
||||
|
return Base64.getEncoder().encodeToString(str.getBytes()); |
||||
|
} |
||||
|
|
||||
|
public static final String strMD5(String s) { |
||||
|
|
||||
|
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', |
||||
|
'a', 'b', 'c', 'd', 'e', 'f' }; |
||||
|
|
||||
|
try { |
||||
|
|
||||
|
byte[] strTemp = s.getBytes(); |
||||
|
MessageDigest mdTemp = MessageDigest.getInstance("MD5"); |
||||
|
mdTemp.update(strTemp); |
||||
|
byte[] md = mdTemp.digest(); |
||||
|
int j = md.length; |
||||
|
char str[] = new char[j * 2]; |
||||
|
int k = 0; |
||||
|
|
||||
|
for (int i = 0; i < j; i++) { |
||||
|
byte byte0 = md[i]; |
||||
|
str[k++] = hexDigits[byte0 >>> 4 & 0xf]; |
||||
|
str[k++] = hexDigits[byte0 & 0xf]; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return new String(str); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,134 @@ |
|||||
|
package com.zdxt.enforcementcode.common.util; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.axis.client.Call; |
||||
|
import org.apache.axis.client.Service; |
||||
|
import org.dromara.common.core.utils.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.scheduling.annotation.Async; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import javax.xml.namespace.QName; |
||||
|
import javax.xml.rpc.ParameterMode; |
||||
|
import java.net.URL; |
||||
|
|
||||
|
/** |
||||
|
* 政务短信平台客户端(深圳政务短信 WebService) |
||||
|
* <p> |
||||
|
* 账号密码由配置 sms.account / sms.pwd 提供(明文存储,发送前经 AZDG 加密)。 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
public class ZwSmsClient { |
||||
|
|
||||
|
private static final QName OPERATION_INSERT_DOWN_SMS = new QName("", "InsertDownSms"); |
||||
|
private static final QName OPERATION_CONN_MAS = new QName("", "ConnMas"); |
||||
|
|
||||
|
/** |
||||
|
* 短信平台账号(明文,发送前经 AZDG 加密) |
||||
|
*/ |
||||
|
@Value("${sms.account}") |
||||
|
private String username; |
||||
|
|
||||
|
@Value("${sms.pwd}") |
||||
|
private String password; |
||||
|
|
||||
|
/** |
||||
|
* 短信平台 WebService 地址 |
||||
|
*/ |
||||
|
@Value("${sms.url}") |
||||
|
private String url; |
||||
|
|
||||
|
/** |
||||
|
* 批次号 |
||||
|
*/ |
||||
|
@Value("${sms.batch}") |
||||
|
private String batch; |
||||
|
|
||||
|
/** |
||||
|
* 异步发送短信,失败仅记录日志,不影响调用方主流程 |
||||
|
* |
||||
|
* @param phone 接收人手机号,多个逗号分隔 |
||||
|
* @param content 短信内容 |
||||
|
*/ |
||||
|
@Async |
||||
|
public void asyncSendSms(String phone, String content) { |
||||
|
if (StringUtils.isBlank(phone) || StringUtils.isBlank(content)) { |
||||
|
log.warn("短信接收手机号或内容为空,跳过发送"); |
||||
|
return; |
||||
|
} |
||||
|
try { |
||||
|
String result = sendMessage(phone, content); |
||||
|
log.info("短信异步发送完成,phone={},平台返回:{}", phone, result); |
||||
|
} catch (Exception e) { |
||||
|
log.error("短信异步发送失败,phone={}", phone, e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 同步发送短信 |
||||
|
* |
||||
|
* @param phone 接收人手机号,多个逗号分隔 |
||||
|
* @param content 短信内容 |
||||
|
* @return 短信平台返回结果 |
||||
|
*/ |
||||
|
public String sendMessage(String phone, String content) throws Exception { |
||||
|
if (StringUtils.isBlank(phone)) { |
||||
|
throw new IllegalArgumentException("短信接收手机号不能为空"); |
||||
|
} |
||||
|
if (StringUtils.isBlank(content)) { |
||||
|
throw new IllegalArgumentException("短信内容不能为空"); |
||||
|
} |
||||
|
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { |
||||
|
throw new IllegalStateException("短信平台账号未配置(sms.account/sms.pwd)"); |
||||
|
} |
||||
|
Integer needReport = 1; |
||||
|
String sendbody = "<sendbody>\n" + |
||||
|
"\t<message>\n" + |
||||
|
"\t<orgaddr></orgaddr><mobile>%s</mobile>" + |
||||
|
"<content><![CDATA[%s]]></content>" + |
||||
|
"<sendtime></sendtime>" + |
||||
|
"<needreport>%s</needreport>\n" + |
||||
|
"\t</message>\n" + |
||||
|
"\t<publicContent></publicContent>\n" + |
||||
|
"</sendbody>"; |
||||
|
return invoke(OPERATION_INSERT_DOWN_SMS, |
||||
|
new String[]{"username", "password", "batch", "sendbody"}, |
||||
|
new Object[]{Azdg.encrypt(username), Azdg.encrypt(password), batch, |
||||
|
String.format(sendbody, phone.trim(), content, needReport)}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证账号密码(联调用,业务发送无需每次调用) |
||||
|
*/ |
||||
|
public String connMas() throws Exception { |
||||
|
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { |
||||
|
throw new IllegalStateException("短信平台账号未配置(sms.account/sms.pwd)"); |
||||
|
} |
||||
|
return invoke(OPERATION_CONN_MAS, |
||||
|
new String[]{"username", "password"}, |
||||
|
new Object[]{Azdg.encrypt(username), Azdg.encrypt(password)}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 统一的 Axis WebService 调用入口 |
||||
|
* |
||||
|
* @param operation 操作名 QName |
||||
|
* @param paramNames 参数名列表,与 args 一一对应 |
||||
|
* @param args 参数值列表 |
||||
|
*/ |
||||
|
private String invoke(QName operation, String[] paramNames, Object[] args) throws Exception { |
||||
|
Service service = new Service(); |
||||
|
Call call = (Call) service.createCall(); |
||||
|
call.setTargetEndpointAddress(new URL(url)); |
||||
|
call.setOperationName(operation); |
||||
|
call.setTimeout(30_000); |
||||
|
for (int i = 0; i < paramNames.length; i++) { |
||||
|
call.addParameter(paramNames[i], org.apache.axis.encoding.XMLType.XSD_STRING, ParameterMode.IN); |
||||
|
} |
||||
|
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING); |
||||
|
String result = (String) call.invoke(args); |
||||
|
log.info("短信平台调用完成,operation={},返回:{}", operation.getLocalPart(), result); |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue