一、阿里雲短信服務使用介紹
1、登錄阿里雲官網,找到短信服務,選擇簽名管理
2、添加簽名,如何添加自己看就可以了,很簡單,簽名內容就是發送短信內容的第一句話,這里注意的就是通用簽名現在只有公司才能用,個人只能用驗證碼簽名
3、除了簽名以外,還要添加短息模板,我們將通過代碼方式調用工具類,傳入簽名、短信模板、手機號來發送驗證碼,模板可以用自動生成的
4、在發送短信時需要進行身份認證,只有認證通過才能發送短信,所以還需要在阿里雲的右上角點擊用戶,獲取密鑰
5、無論你選則下面哪個都行,我們選擇子用戶,指定用戶權限,而不是分配所有權限。
6、我們要點擊編程訪問
7、新建用戶成功后要進行授權,自己找找,懶得放圖片了,找到創建的用戶就能看到授權兩個字了
8、給新建的用戶添加權限內容,搜索一下短信服務,兩個都點上
9、然后就生成密鑰,就是要注意,因為是點擊的編程訪問,所以密鑰一定要記得復制然后保存,因為只會出現這一次,以后再也不會出現(我說的密鑰就是下圖的KeyID和KeySecret)
10、最后記得,這個服務要錢的,只不過不貴就是了
11、java使用短信驗證碼api在官網上就能找到,用戶指南啥的,懶得去看了,我直接把我改了下的工具類放在這吧
/** * 阿里雲短信驗證工具類 * */ public class AliSNMUtil { public static final String TEMPLET_IDENTIFYING ="SMS_20475xxxx";//發送驗證碼的模板 /** * * 發送短信驗證碼 * phone:發送給哪個電話號碼,需傳入 * identifyingCode:發送的驗證碼內容 * templet:傳入短信模板,阿里雲里面有 */ public static void sendVerification(String phone,Object identifyingCode,String templet) throws ClientException { //設置超時時間-可自行調整 System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "10000"); //初始化ascClient需要的幾個參數 final String product = "Dysmsapi";//短信API產品名稱(短信產品名固定,無需修改) final String domain = "dysmsapi.aliyuncs.com";//短信API產品域名(接口地址固定,無需修改) //替換成你的AK final String accessKeyId = "xxxxxxxxxxxxxxxxxxx";//你的accessKeyId,參考本文檔步驟2 final String accessKeySecret = "xxxxxxxxxxxxxxxx";//你的accessKeySecret,參考本文檔步驟2 //初始化ascClient,暫時不支持多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(); //使用post提交 request.setMethod(MethodType.POST); //必填:待發送手機號。支持以逗號分隔的形式進行批量調用,批量上限為1000個手機號碼,批量調用相對於單條調用及時性稍有延遲,驗證碼類型的短信推薦使用單條調用的方式;發送國際/港澳台消息時,接收號碼格式為國際區號+號碼,如“85200000000” request.setPhoneNumbers(phone); //必填:短信簽名-可在短信控制台中找到 request.setSignName("ABC商城"); //必填:短信模板-可在短信控制台中找到,發送國際/港澳台消息時,請使用國際/港澳台短信模版 request.setTemplateCode(templet); //可選:模板中的變量替換JSON串,如模板內容為"親愛的${name},您的驗證碼為${code}"時,此處的值為 //友情提示:如果JSON中需要帶換行符,請參照標准的JSON協議對換行符的要求,比如短信內容中包含\r\n的情況在JSON中需要表示成\\r\\n,否則會導致JSON在服務端解析失敗 //參考:request.setTemplateParam("{\"變量1\":\"值1\",\"變量2\":\"值2\",\"變量3\":\"值3\"}") request.setTemplateParam("{\"code\":\""+identifyingCode+"\"}"); //可選-上行短信擴展碼(擴展碼字段控制在7位或以下,無特殊需求用戶請忽略此字段) //request.setSmsUpExtendCode("90997"); //可選:outId為提供給業務方擴展字段,最終在短信回執消息中將此值帶回給調用者 request.setOutId("yourOutId"); //請求失敗這里會拋ClientException異常 SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) { //請求成功 System.out.println("發送成功!"); } } }
12、但是,你只復制了一個工具類,肯定滿篇報錯滿篇紅,別急,依賴都沒加,玩個屁啊
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>3.3.1</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-dysmsapi</artifactId> <version>1.0.0</version> </dependency>
二、驗證碼校驗思路
在項目中,你要發驗證碼簡單,但你得校驗啊,不是一哆嗦把短信發了然后就提褲子走人,你得負責啊,別人把驗證碼輸入了,你怎么確定他輸入正確呢?
思路非常簡單的,直接在redis中保存就好了,用收驗證碼的手機號碼做key,用驗證碼內容做值,存儲五分鍾,發驗證碼之前先在redis中存儲一份,提交表單后拿輸入的驗證碼跟redis中的驗證碼匹配一下就知道對不對了。步驟搞起來:
1、因為要用到redis,所以還得加redis依賴,下面就不細分步驟了,直接跟着一步步來就可以
依賴:我沒有指定版本號,自己選擇比較好
<dependencies> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <!-- 指定端口 --> <port>84</port> <!-- 請求路徑 --> <path>/</path> </configuration> </plugin> </plugins> </build>
配置applicationContext-redis.xml,spring整合redis
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--Jedis連接池的相關配置--> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal"> <value>200</value> </property> <property name="maxIdle"> <value>50</value> </property> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="true"/> </bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool"> <constructor-arg name="poolConfig" ref="jedisPoolConfig" /> <constructor-arg name="host" value="127.0.0.1" /> <constructor-arg name="port" value="6379" type="int" /> <constructor-arg name="timeout" value="30000" type="int" /> </bean> </beans>
日志文件,log4j.properties
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c:\\mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=debug, stdout
配置web.xml,啟動加載spring容器
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Archetype Created Web Application</display-name> <!-- 加載spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <!-- 下面的兩個 * ,前面一個表示當前工程依賴的工程里面如果有相同文件名的配置,也會被當前工程加載 后面一個表示這個文件名后面無論是什么,都會被這個工程加載進來 這里前面一個*可以不用,后面那個得要,因為我要加載兩個配置文件,如果不加的話,需要在其中一個配置文件中引入另一個配置文件--> <param-value>classpath*:applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
這樣創建的工程環境應該就沒有問題了,如果出現什么爆紅什么的,自己動動手看看什么情況吧,可能是格式錯誤
2、現在開始調用工具類發送驗證碼,並將驗證碼存入redis中
/** * 發送驗證碼 * */public class Test001{ /** * 發送驗證碼 * */
@Test
public static void main test02(){ try { //生成驗證碼,我用的是工具類,RandomizationUtil,在我的小工具分類的隨筆中有 Integer identifyingCode = (RandomizationUtil.generateValidateCode(6)); //將驗證碼存入redis五分鍾,第一個參數是電話號,第二個是在redis中存多久,單位是秒,第三個是生成的驗證碼 jedisPool.getResource().setex(13117499999,60*5,identifyingCode.toString()); //調用方法發送短信,參數去看發送驗證碼的工具類就行了,在上面 AliSNMUtil.sendVerification(13117499999,identifyingCode.toString(),ALiSNMUtil.TEMPLET_IDENTIFYING); return new Result(true,"驗證碼發送成功"); } catch (ClientException e) { e.printStackTrace(); return new Result(true,"驗證碼發送失敗"); } } }
3、從redis中取驗證碼比較,上面這段代碼和下面這段代碼不要拷貝,因為我是從自己項目中拷貝出來的,隨意修改,只需要看用了什么方法就行了,代碼不多
//校驗驗證碼是否正確,第一行代碼是操作redis,根據key獲取值,第二行代碼是從map中獲取用戶輸入的驗證碼,第三行就是判斷了 String redisVerificationCode = jedisPool.getResource().get(telephone); String validateCode = (String) map.get("validateCode"); if (StringUtils.isEmpty(redisVerificationCode)|| StringUtils.isEmpty(validateCode)||!redisVerificationCode.equals(validateCode)) { return new Result(false, MessageConstant.VALIDATECODE_ERROR);