讀古今文學網 > Maven實戰 > 10.1.2 account-captcha的主代碼 >

10.1.2 account-captcha的主代碼

account-captcha需要提供的服務是生成隨機的驗證碼主鍵,然後用戶可以使用這個主鍵要求服務生成一個驗證碼圖片,這個圖片對應的值應該是隨機的,最後用戶用肉眼讀取圖片的值,並將驗證碼的主鍵與這個值交給服務進行驗證。這一服務對應的接口可以定義,如代碼清單10-3所示。

代碼清單10-3 AccountCaptchaService.java

很顯然,generateCaptchaKey()用來生成隨機的驗證碼主鍵,generateCaptchaImage()用來生成驗證碼圖片,而validateCaptcha()用來驗證用戶反饋的主鍵和值。

該接口定義了額外的getPreDefinedTexts()和setPreDefinedTexts()方法,通過這一組方法,用戶可以預定義驗證碼圖片的內容,同時也提高了可測試性。如果AccountCaptchaService永遠生成隨機的驗證碼圖片,那麼沒有人工的參與就很難測試該功能。現在,服務允許傳入一個文本列表,這樣就可以基於這些文本生成驗證碼,那麼我們也就能控制驗證碼圖片的內容了。

為了能夠生成隨機的驗證碼主鍵,引入一個RandomGenerator類,見代碼清單10-4。

代碼清單10-4 RandomGenerator.java

RandomGenerator類提供了一個靜態且線程安全的getRandomString()方法。該方法生成一個長度為8的字符串,每個字符都是隨機地從所有數字和字母中挑選,這裡主要是使用了java.util.Random類,其nextInt(int n)方法會返回一個大於等於0且小於n的整數。代碼中的字段range包含了所有的數字與字母,將其長度傳給nextInt()方法後就能獲得一個隨機的下標,再調用range.charAt()就可以隨機取得一個其包含的字符了。

現在看AccountCaptchaService的實現類AccountCaptchaServiceImpl。首先需要初始化驗證碼圖片生成器,見代碼清單10-5。

代碼清單10-5 AccountCaptchaServiceImpl.java的afterPropertySet()方法

AccountCaptchaServiceImpl實現了SpringFramework的InitializingBean接口,該接口定義了一個方法afterPropertiesSet(),該方法會被SpringFramework初始化對象的時候調用。該代碼清單中使用該方法初始化驗證碼生成器producer,並且為producer提供了默認的配置。

接著AccountCaptchaServiceImpl需要實現generateCaptchaKey()方法,見代碼清單10-6。

代碼清單10-6 AccountCaptchaServiceImpl.java的generateCaptchaKey()方法

上述代碼清單中的generateCaptchaKey()首先生成一個隨機的驗證碼主鍵,每個主鍵將和一個驗證碼字符串相關聯,然後這組關聯會被存儲到captchaMap中以備將來驗證。主鍵的目的僅僅是標識驗證碼圖片,其本身沒有實際的意義。代碼清單中的getCaptchaText()用來生成驗證碼字符串,當preDefinedTexts不存在或者為空的時候,就是用驗證碼圖片生成器producer創建一個隨機的字符串,當preDefinedTexts不為空的時候,就順序地循環該字符串列表讀取值。preDefinedTexts有其對應的一組get和set方法,這樣就能讓用戶預定義驗證碼字符串的值。

有了驗證碼圖片的主鍵,AccountCaptchaServiceImpl就需要實現generateCaptchaImage()方法來生成驗證碼圖片,見代碼清單10-7。

代碼清單10-7 AccountCaptchaServiceImpl.java的generateCaptchaImage()方法

為了生成驗證碼圖片,就必須先得到驗證碼字符串的值,代碼清單中通過使用主鍵來查詢captchaMap獲得該值,如果值不存在,就拋出異常。有了驗證碼字符串的值之後,generateCaptchaImage()方法就能通過producer來生成一個BufferedImage,隨後的代碼將這個圖片對像轉換成jpg格式的字節數組並返回。有了該字節數組,用戶就能隨意地將其保存成文件,或者在網頁上顯示。

最後是簡單的驗證過程,見代碼清單10-8。

代碼清單10-8 AccountCaptchaServiceImpl.java的validateCaptcha()方法

用戶得到了驗證碼圖片以及主鍵後,就會識別圖片中所包含的字符串信息,然後將此驗證碼的值與主鍵一起反饋給validateCaptcha()方法以進行驗證。validateCaptcha()通過主鍵找到正確的驗證碼值,然後與用戶提供的值進行比對,如果成功,則返回true。

當然,還需要一個SpringFramework的配置文件,它在資源目錄src/main/resources/下,名為account-captcha.xml,見代碼清單10-9。

代碼清單10-9 account-captcha.xml

這是一個最簡單的SpringFramework配置,它定義了一個id為accountCaptchaService的bean,其實現為剛才討論的AccountCaptchaServiceImpl。