import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.octo.captcha.Captcha;
import com.octo.captcha.engine.CaptchaEngine;
import com.octo.captcha.service.CaptchaServiceException;
import com.octo.captcha.service.captchastore.CaptchaStore;
import com.octo.captcha.service.text.TextCaptchaService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* SMSCaptchaService
*
* @author hsdllcw
*
*/
@Service
public class SMSCaptchaService implements TextCaptchaService {
public static String product;
public static String domain;
public static String accessKeyId;
public static String accessKeySecret;
public static String signName;
public static String templateCode;
public static String isDev;
protected CaptchaStore store;
protected CaptchaEngine engine;
protected Logger logger;
@SuppressWarnings("all")
public SMSCaptchaService(
CaptchaStore captchaStore,
SMSEngine captchaEngine,
String product,
String domain,
String accessKeyId,
String accessKeySecret,
String signName,
String templateCode,
String isDev
){
if (captchaEngine == null || captchaStore == null)
throw new IllegalArgumentException("Store or gimpy can't be null");
this.engine = captchaEngine;
this.store = captchaStore;
this.product=product;
this.domain=domain;
this.accessKeyId=accessKeyId;
this.accessKeySecret=accessKeySecret;
this.signName=signName;
this.templateCode=templateCode;
this.isDev=isDev;
logger = LoggerFactory.getLogger(this.getClass());
logger.info("Init " + this.store.getClass().getName());
this.store.initAndStart();
}
public Map<String,Object> sendSms(String phoneNumber,String code) {
Map<String,Object> data=new HashMap<String,Object>();
//超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
try {
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装参数
SendSmsRequest request = new SendSmsRequest();
request.setPhoneNumbers(phoneNumber);
request.setSignName(signName);
request.setTemplateCode(templateCode);
request.setTemplateParam("{\"code\":\""+code+"\"}");
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
String statusOK="OK";
if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")){
data.put("status",true);
data.put("msg",code);
}else {
data.put("status",false);
data.put("msg","未知错误");
QuerySendDetailsResponse querySendDetailsResponse = querySendDetails(sendSmsResponse.getBizId(),phoneNumber);
System.out.println("短信明细查询接口返回数据----------------");
System.out.println("Code=" + querySendDetailsResponse.getCode());
System.out.println("Message=" + querySendDetailsResponse.getMessage());
int i = 0;
for(QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse.getSmsSendDetailDTOs())
{
System.out.println("SmsSendDetailDTO["+i+"]:");
System.out.println("Content=" + smsSendDetailDTO.getContent());
System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode());
System.out.println("OutId=" + smsSendDetailDTO.getOutId());
System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum());
System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate());
System.out.println("SendDate=" + smsSendDetailDTO.getSendDate());
System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus());
System.out.println("Template=" + smsSendDetailDTO.getTemplateCode());
}
System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount());
System.out.println("RequestId=" + querySendDetailsResponse.getRequestId());
}
}catch (ClientException e){
data.put("status",false);
data.put("msg",e.getErrMsg());
}
return data;
}
public QuerySendDetailsResponse querySendDetails(String bizId,String phoneNumber) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
QuerySendDetailsRequest request = new QuerySendDetailsRequest();
//必填-号码
request.setPhoneNumber(phoneNumber);
//可选-流水号
request.setBizId(bizId);
//必填-发送日期 支持30天内记录查询,格式yyyyMMdd
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
request.setSendDate(ft.format(new Date()));
//必填-页大小
request.setPageSize(10L);
//必填-当前页码从1开始计数
request.setCurrentPage(1L);
//hint 此处可能会抛出异常,注意catch
QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
return querySendDetailsResponse;
}
@Override
public String getTextChallengeForID(String ID) throws CaptchaServiceException {
return (String)this.getChallengeForID(ID);
}
@Override
public String getTextChallengeForID(String ID, Locale locale) throws CaptchaServiceException {
return (String) this.getChallengeForID(ID, locale);
}
public String getTextChallengeForID(String ID, Locale locale,String phoneNumber) throws CaptchaServiceException {
if("true".equals(isDev)){
return sendSms(phoneNumber,this.getTextChallengeForID(ID, locale)).get("status").toString();
}else {
System.out.println(this.getTextChallengeForID(ID, locale));
return "true";
}
}
@Override
public Object getChallengeForID(String ID) throws CaptchaServiceException {
return this.getChallengeForID(ID, Locale.getDefault());
}
@Override
public Object getChallengeForID(String ID, Locale locale) throws CaptchaServiceException {
Captcha captcha;
Object challenge;
//check if has capthca
if (!this.store.hasCaptcha(ID)) {
//if not generate and store
captcha = generateAndStoreCaptcha(locale, ID);
} else {
//else get it
captcha = this.store.getCaptcha(ID);
if (captcha == null) {
captcha = generateAndStoreCaptcha(locale, ID);
} else {
//if dirty
if (captcha.hasGetChalengeBeenCalled().booleanValue()) {
//get a new one and store it
captcha = generateAndStoreCaptcha(locale, ID);
}
//else nothing
}
}
challenge = getChallengeClone(captcha);
captcha.disposeChallenge();
return challenge;
}
@Override
public String getQuestionForID(String ID) throws CaptchaServiceException {
return this.getQuestionForID(ID, Locale.getDefault());
}
public String getQuestionForID(String ID, Locale locale) throws CaptchaServiceException {
Captcha captcha;
//check if has capthca
if (!this.store.hasCaptcha(ID)) {
//if not generate it
captcha = generateAndStoreCaptcha(locale, ID);
} else {
captcha = this.store.getCaptcha(ID);
if (captcha == null) {
captcha = generateAndStoreCaptcha(locale, ID);
}else if (locale != null) {
Locale storedlocale = this.store.getLocale(ID);
if (!locale.equals(storedlocale)) {
captcha = generateAndStoreCaptcha(locale, ID);
}
}
}
return captcha.getQuestion();
}
@Override
public Boolean validateResponseForID(String ID, Object response)
throws CaptchaServiceException {
if (!store.hasCaptcha(ID)) {
throw new CaptchaServiceException("Invalid ID, could not validate unexisting or already validated captcha");
} else {
Boolean valid = store.getCaptcha(ID).validateResponse(response);
store.removeCaptcha(ID);
return valid;
}
}
protected Captcha generateAndStoreCaptcha(Locale locale, String ID) {
Captcha captcha = engine.getNextCaptcha(locale);
this.store.storeCaptcha(ID, captcha, locale);
return captcha;
}
protected Object getChallengeClone(Captcha captcha) {
return new StringBuilder(captcha.getChallenge().toString()).toString();
}
public Boolean tryResponseForID(String ID, Object response, boolean removeOnError) throws CaptchaServiceException {
if (!store.hasCaptcha(ID)) {
throw new CaptchaServiceException("Invalid ID, could not validate unexisting or already validated captcha");
} else {
Boolean valid = store.getCaptcha(ID).validateResponse(response);
if (removeOnError) {
store.removeCaptcha(ID);
}
return valid;
}
}
}