云片网短信发送工作记录
由于我这儿云片网发送短信少,所以直接写死,这儿封装了阿里华为云片等发送短信的方法
public class SmsUtil { private static final String YUNPIAN_SEND_SMS_URL = "https://sms.yunpian.com/v2/sms/single_send.json"; private static final String API_KEY = "xxxxxxxxxxxx"; // 云片网API Key private static final String SIGN_NAME = "xxxxxxx"; // 短信签名 public static SendSmsResponse send(Record smsConfig, String phone, String data) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException, IOException { String url = "https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1"; //String sender = "8822021405177"; String sender = smsConfig.getStr("sender"); String accessKeyId = smsConfig.getStr("access_key"); String accessKeySecret = smsConfig.getStr("access_key_secret"); String templateId = smsConfig.getStr("template_code"); String signature = smsConfig.getStr("sign_name"); String statusCallBack = ""; String templateParas = data; String receiver = phone; if (!phone.startsWith("+86")) { receiver = "+86" + phone; } String body = buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, signature); if (null != body && !body.isEmpty()) { String wsseHeader = buildWsseHeader(accessKeyId, accessKeySecret); if (null != wsseHeader && !wsseHeader.isEmpty()) { CloseableHttpClient client = HttpClients.custom().setSSLContext((new SSLContextBuilder()).loadTrustMaterial((KeyStore) null, (x509CertChain, authType) -> { return true; }).build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build(); HttpResponse response = client.execute(RequestBuilder.create("POST").setUri(url).addHeader("Content-Type", "application/x-www-form-urlencoded").addHeader("Authorization", "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"").addHeader("X-WSSE", wsseHeader).setEntity(new StringEntity(body)).build()); System.out.println(response.toString()); String enitiyResult = EntityUtils.toString(response.getEntity()); System.out.println(enitiyResult); Map<String, Object> result = (Map) JSON.parseObject(enitiyResult, new TypeReference<Map<String, Object>>() { }, new Feature[0]); System.out.println(result); SendSmsResponse sendSmsResponse = new SendSmsResponse(); String resultCode = ""; if (result.containsKey("code")) { resultCode = result.get("code").toString(); if ("000000".equals(resultCode)) { resultCode = "OK"; } } sendSmsResponse.setCode(resultCode); sendSmsResponse.setMessage(String.valueOf(result.get("description"))); return sendSmsResponse; } else { System.out.println("wsse header is null."); return null; } } else { System.out.println("body is null."); return null; } } //阿里发送短信的发送方法如下 public static com.aliyun.dysmsapi20170525.models.SendSmsResponse newSend(Record smsConfig, String phone, String data) throws Exception { // 从配置中获取阿里云短信服务的参数 String accessKeyId = smsConfig.getStr("access_key"); String accessKeySecret = smsConfig.getStr("access_key_secret"); String signName = smsConfig.getStr("sign_name"); String templateCode = smsConfig.getStr("template_code"); // 配置阿里云客户端 Config config = new Config() .setAccessKeyId(accessKeyId) .setAccessKeySecret(accessKeySecret); config.endpoint = "dysmsapi.aliyuncs.com"; // 创建客户端 Client client = new Client(config); // 构造请求参数 SendSmsRequest sendSmsRequest = new SendSmsRequest() .setPhoneNumbers(phone) .setSignName(signName) .setTemplateCode(templateCode) .setTemplateParam("{\"code\":\"" + data + "\"}"); // 发送短信 com.aliyun.dysmsapi20170525.models.SendSmsResponse response = client.sendSms(sendSmsRequest); return response; } // 云片网发送云片网的短信如下。如果模板审核原因,只能申请到注册的模板,其它模板无法通过。 // 所以估记这个方法估记很少用,临时用一下,所以参数直接写死算了 public static String yunSend(String phone, String data) { String text = "【" + SIGN_NAME + "】正在进行登录操作,您的验证码是" + data; // 短信内容 try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost post = new HttpPost(YUNPIAN_SEND_SMS_URL); List<NameValuePair> params = new ArrayList<>(); params.add(new BasicNameValuePair("apikey", API_KEY)); params.add(new BasicNameValuePair("mobile", phone)); params.add(new BasicNameValuePair("text", text)); post.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); try (CloseableHttpResponse response = client.execute(post)) { String result = EntityUtils.toString(response.getEntity(), "UTF-8"); return result; } } catch (Exception e) { e.printStackTrace(); return "Error: " + e.getMessage(); } } static String buildRequestBody(String sender, String receiver, String templateId, String templateParas, String statusCallbackUrl, String signature) { if (null != sender && null != receiver && null != templateId && !sender.isEmpty() && !receiver.isEmpty() && !templateId.isEmpty()) { List<NameValuePair> keyValues = new ArrayList(); keyValues.add(new BasicNameValuePair("from", sender)); keyValues.add(new BasicNameValuePair("to", receiver)); keyValues.add(new BasicNameValuePair("templateId", templateId)); if (null != templateParas && !templateParas.isEmpty()) { keyValues.add(new BasicNameValuePair("templateParas", templateParas)); } if (null != statusCallbackUrl && !statusCallbackUrl.isEmpty()) { keyValues.add(new BasicNameValuePair("statusCallback", statusCallbackUrl)); } if (null != signature && !signature.isEmpty()) { keyValues.add(new BasicNameValuePair("signature", signature)); } return URLEncodedUtils.format(keyValues, Charset.forName("UTF-8")); } else { System.out.println("buildRequestBody(): sender, receiver or templateId is null."); return null; } } static String buildWsseHeader(String appKey, String appSecret) { if (null != appKey && null != appSecret && !appKey.isEmpty() && !appSecret.isEmpty()) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); String time = sdf.format(new Date()); String nonce = UUID.randomUUID().toString().replace("-", ""); byte[] passwordDigest = DigestUtils.sha256(nonce + time + appSecret); String hexDigest = Hex.encodeHexString(passwordDigest); String passwordDigestBase64Str = Base64.getEncoder().encodeToString(hexDigest.getBytes()); return String.format("UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"", appKey, passwordDigestBase64Str, nonce, time); } else { System.out.println("buildWsseHeader(): appKey or appSecret is null."); return null; } } public static void main(String[] args) throws Exception { String phone = "18675918218"; // 替换为实际测试手机号 // 测试验证码 String data = "123456"; // 验证码 // 调用yunSend方法发送短信 String result = SmsUtil.yunSend(phone, data); // 打印发送结果 System.out.println("发送结果: " + result); } }
最后是关于如何发送短信的代码
public void sendVcode() { String ct = getPara("ct"); Long companyId; if (StringUtil.isNotEmpty(ct)) { companyId = Db.queryLong("select id from fr_company where token = ? ", ct); } else { Record user = getRequestUser(); if (null != user) { companyId = user.getLong("company_id"); } else { companyId = CompanyData.getPlatformId(); } } String phone = getPara("phone"); Integer type = getParaToInt("type"); Random ran = new Random(); Integer icode; // 验证码是随机的 while ((icode = ran.nextInt(10000)) < 1000) { icode = ran.nextInt(); } String vcode = String.valueOf(icode); logger.info("手机号码:{},验证码:{},type={},companyId={}", phone, vcode, type, companyId); Integer timeToLive = 900; // 默认900秒 Record smsConfig = CompanyExtendResource.loadSmsConfig(companyId, type); if (null == smsConfig) { smsConfig = CompanyExtendResource.loadSmsConfig(CompanyData.getPlatformId(), type); logger.info("can not find smsConfig by companyId:{}", companyId); renderJson(JsonResult.fail("-1").show("发送失败")); return; } logger.info("smsConfig:{}", smsConfig.getColumns()); Integer status = smsConfig.getInt("status"); if (status == 1) { try { // 先尝试使用云片网发送短信 String yunpianResponse = SmsUtil.yunSend(phone, vcode); logger.info("云片网发送结果: {}", yunpianResponse); // 解析云片网返回的 JSON 结果 String code = null; try { JSONObject responseJson = new JSONObject(yunpianResponse); code = responseJson.getString("code"); } catch (Exception e) { logger.error("解析云片网返回的 JSON 数据时出错: {}", yunpianResponse, e); renderJson(JsonResult.fail("-1").show("解析云片网返回的 JSON 数据时出错")); return; } if ("0".equals(code)) { // 云片网发送成功 logger.info("云片网发送成功,手机号:{}", phone); renderJson(JsonResult.success()); } else { // 云片网发送失败,记录日志并尝试使用阿里云发送短信 logger.info("云片网发送失败,正在调用阿里云发送短信,手机号:{}", phone); SendSmsResponse aliResponse = SmsUtil.newSend(smsConfig, phone, vcode); if (aliResponse != null) { logger.info("阿里云发送结果: code:{}, message:{}", aliResponse.getBody().getCode(), aliResponse.getBody().getMessage()); if ("OK".equalsIgnoreCase(aliResponse.getBody().getCode())) { // 阿里云发送成功 logger.info("阿里云发送成功,手机号:{}", phone); renderJson(JsonResult.success()); } else { // 阿里云发送失败 logger.info("阿里云发送失败,手机号:{}", phone); if (aliResponse.getBody().getCode().indexOf("BUSINESS_LIMIT_CONTROL") > -1) { renderJson(JsonResult.fail("-1").show("验证码发送已达上限")); } else { renderJson(JsonResult.fail("-1").show("验证码发送失败")); } } } else { logger.info("阿里云发送失败,未获取到响应,手机号:{}", phone); renderJson(JsonResult.fail("-1").show("验证码发送失败")); } } } catch (Exception e) { e.printStackTrace(); logger.error("发送短信时发生异常,手机号:{}", phone, e); renderJson(JsonResult.fail("-1").show("验证码发送失败")); } } else { renderJson(JsonResult.successWithData(vcode)); } // 保存到 Redis String key = "user:" + type + ":" + phone; RedisManager.handler().set(key, vcode, timeToLive); }
浙公网安备 33010602011771号