ssm中的短信驗證碼的實現


這次測試采用的是http://www.webchinese.com.cn/default.shtml平台的服務,代碼參考了https://blog.csdn.net/qq_33165600/article/details/79506936

首先下載所需jar包:commons-logging-1.1.1.jar,commons-httpclient-3.1.jar,commons-codec-1.4.jar 。

到網站注冊好賬號,記下自己的賬戶和密鑰(不是登錄密碼)。

簽名就是短信最開始【】括住的部分。

發送短信生成驗證碼的工具類:

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;

import java.io.IOException;
import java.util.HashMap;
import java.util.Random;

public class SendMessage {
    public static void main(String[] args) throws Exception{
        SendMessage sendMessage = new SendMessage();
        sendMessage.getMessageStatus("你的手機號碼");
    }
    public HashMap<String,String> getMessageStatus(String phone) throws HttpException, IOException {
        HashMap<String,String> m = new HashMap<String,String>();
        //http協議
        HttpClient client = new HttpClient();
        //連接第三方平台
        PostMethod post = new PostMethod("http://gbk.api.smschinese.cn/");
        post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=gbk");//在頭文件中設置轉碼


        //生成六位驗證碼
        String charValue = "";
        for (int i = 0; i < 6; i++) {
            char c = (char) (randomInt(0, 9) + '0');
            charValue += String.valueOf(c);
        }
        //短信模板
        NameValuePair[] data ={
                new NameValuePair("Uid", "scxdhr"), //sms短信通 注冊的用戶名
                new NameValuePair("Key", "d41d8cd98f00b204e980"), //密匙
                new NameValuePair("smsMob",phone),//要發送的手機號
                new NameValuePair("smsText","您的驗證碼是:"+charValue)//短信內容
        };

        post.setRequestBody(data);
        client.executeMethod(post);
        //獲取http頭
        Header[] headers = post.getResponseHeaders();
        int statusCode = post.getStatusCode();

        System.out.println("statusCode:"+statusCode);

        for(Header h:headers){
            System.out.println(h.toString());
        }
        //獲取返回消息
        String result = new String(post.getResponseBodyAsString().getBytes("gbk"));
        System.out.println(result); //打印返回消息狀態
        //將返回消息和6位數驗證碼放入到m列表里面
        m.put("result", result);
        m.put("code", charValue);
        //斷開與第三方平台的連接
        post.releaseConnection();

        return m;

    }
    //生成驗證碼
    public static int randomInt(int from, int to) {
        Random r = new Random();
        return from + r.nextInt(to - from);
    }
}

 

result返回“1”就表示發送成功,手機上也會收到短信。

 

有三種方法在后台獲得手機驗證碼:

 

1.使用session的setAttribute方法,把數據存到頁面緩存中,但是關了頁面之后,儲存的驗證碼就會失效,所以不推薦使用這種方法。

 

2.使用redis數據庫緩存驗證碼,redis數據庫用來做這個契合度非常高,還能設置緩存失效時間,寫起來非常簡單。

 

3.寫了一個工具類CacheUtil,一個緩存用的map,也可以設置數據的失效時間,下面貼上代碼:

import java.util.Map;
import java.util.concurrent.*;

/**
 * 緩存工具類
 *
 * @author lance
 * @since 2018-10-25
 */
public class CacheUtil
{
    /**
     * 存儲需緩存數據的map
     */
    private final static Map<String, Entity> MAP = new ConcurrentHashMap<>();
    /**
     * 定時器線程池,用於清除過期緩存
     */
    private final static ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();

    /**
     * 添加緩存
     *
     * @param key  map的key
     * @param data map的value
     */
    public synchronized static void put(String key, Object data)
    {
        CacheUtil.put(key, data, 0);
    }

    /**
     * 添加緩存
     *
     * @param key    map的key
     * @param data   map的value
     * @param expire 過期時間,單位:毫秒, 0表示無限長
     */
    public synchronized static void put(String key, Object data, long expire)
    {
        //清除原map
        CacheUtil.remove(key);
        //設置過期時間
        if (expire > 0)
        {
            Future future = EXECUTOR.schedule(() ->
            {
                //過期后清除該map
                synchronized (CacheUtil.class)
                {
                    MAP.remove(key);
                }
            }, expire, TimeUnit.MILLISECONDS);
            MAP.put(key, new Entity(data, future));
        }
        else
        {
            //不設置過期時間
            MAP.put(key, new Entity(data, null));
        }
    }

    /**
     * 校驗緩存中是否存在key
     *
     * @param key map的key
     * @return 是否存在key
     */
    public synchronized static boolean keyExists(String key)
    {
        return MAP.get(key) != null;
    }

    /**
     * 讀取緩存
     *
     * @param key map的key
     * @return map的value
     */
    public synchronized static Object get(String key)
    {
        Entity entity = MAP.get(key);
        return entity == null ? null : entity.getValue();
    }

    /**
     * 讀取緩存
     *
     * @param key 鍵
     * @param cls 值類型
     * @return map中value存儲的對象
     */
    public synchronized static <T> T get(String key, Class<T> cls)
    {
        return cls.cast(CacheUtil.get(key));
    }

    /**
     * 清除緩存
     *
     * @param key map的key
     * @return
     */
    public synchronized static void remove(String key)
    {
        //清除原緩存數據
        Entity entity = MAP.remove(key);

        //清除原map定時器
        if (null != entity)
        {
            Future future = entity.getFuture();
            if (future != null)
            {
                future.cancel(true);
            }
        }
    }

    /**
     * 緩存實體類
     */
    private static class Entity
    {
        /**
         * map的值
         */
        private Object value;
        /**
         * 定時器
         */
        private Future future;

        private Entity(Object value, Future future)
        {
            this.value = value;
            this.future = future;
        }

        /**
         * 獲取map值
         *
         * @return map值
         */
        public Object getValue()
        {
            return value;
        }

        /**
         * 獲取Future對象
         *
         * @return Future對象
         */
        private Future getFuture()
        {
            return future;
        }
    }
}

 

剩下的就是校驗手機和前台發送過來的驗證碼是否一致,不再贅述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM