springMVC+Java驗證碼完善註冊功能

明天還有我發表於2016-02-29

這篇文章簡單的寫了一個java驗證碼,為之前寫過的springMVC註冊功能加上驗證碼,驗證碼的作用就不多說了,防止機器人程式惡意註冊什麼的。。。

基本的註冊功能的實現請檢視之前的文章Maven搭建springMVC+spring+hibernate實現使用者註冊

其中,我修改了該註冊程式的部分程式碼,其中User.java,加上了password和code的屬性,同時將password持久到資料庫,code屬性使用@transient註解使其不被持久到資料庫。

User.java 中加上這兩個屬性,至於User的構造方法修改為public User(String id, Date regtime, String username,String password) 就不貼程式碼了。

privateString password;
    @Column(name="password",nullable=false,length=20)
    publicString getPassword() {
        returnpassword;
    }
 
    publicvoidsetPassword(String password) {
        this.password = password;
    }
    privateString code;
    @Transient  //不需要持久到DB的屬性使用該註解
    publicString getCode() {
        returncode;
    }
     
    publicvoidsetCode(String code) {
        this.code = code;
    }

?

下面是驗證碼生成的controller,大部分程式碼都寫上了註釋。

CodeController.java

packagecom.sgl.controller;
 
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Graphics;
importjava.awt.image.BufferedImage;
importjava.io.IOException;
importjava.util.Random;
 
importjavax.imageio.ImageIO;
importjavax.servlet.ServletOutputStream;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjavax.servlet.http.HttpSession;
 
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
 
@Controller
publicclass CodeController {
    privateint width = 90;//定義圖片的width
    privateint height = 20;//定義圖片的height
    privateint codeCount = 4;//定義圖片上顯示驗證碼的個數
    privateint xx = 15;
    privateint fontHeight = 18;
    privateint codeY = 16;
    char[] codeSequence = { 'A','B','C','D','E','F','G','H','I','J',
            'K','L','M','N','O','P','Q','R','S','T','U','V','W',
            'X','Y','Z','0','1','2','3','4','5','6','7','8','9'};
 
    @RequestMapping("/code")
    publicvoid getCode(HttpServletRequest req, HttpServletResponse resp)
            throwsIOException {
 
        // 定義影像buffer
        BufferedImage buffImg = newBufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
//      Graphics2D gd = buffImg.createGraphics();
        //Graphics2D gd = (Graphics2D) buffImg.getGraphics();
        Graphics gd = buffImg.getGraphics();
        // 建立一個隨機數生成器類
        Random random = newRandom();
        // 將影像填充為白色
        gd.setColor(Color.WHITE);
        gd.fillRect(0,0, width, height);
 
        // 建立字型,字型的大小應該根據圖片的高度來定。
        Font font = newFont("Fixedsys", Font.BOLD, fontHeight);
        // 設定字型。
        gd.setFont(font);
 
        // 畫邊框。
        gd.setColor(Color.BLACK);
        gd.drawRect(0,0, width - 1, height - 1);
 
        // 隨機產生40條干擾線,使圖象中的認證碼不易被其它程式探測到。
        gd.setColor(Color.BLACK);
        for(inti = 0; i < 40; i++) {
            intx = random.nextInt(width);
            inty = random.nextInt(height);
            intxl = random.nextInt(12);
            intyl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }
 
        // randomCode用於儲存隨機產生的驗證碼,以便使用者登入後進行驗證。
        StringBuffer randomCode = newStringBuffer();
        intred = 0, green = 0, blue = 0;
 
        // 隨機產生codeCount數字的驗證碼。
        for(inti = 0; i < codeCount; i++) {
            // 得到隨機產生的驗證碼數字。
            String code = String.valueOf(codeSequence[random.nextInt(36)]);
            // 產生隨機的顏色分量來構造顏色值,這樣輸出的每位數字的顏色值都將不同。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
 
            // 用隨機產生的顏色將驗證碼繪製到影像中。
            gd.setColor(newColor(red, green, blue));
            gd.drawString(code, (i + 1) * xx, codeY);
 
            // 將產生的四個隨機陣列合在一起。
            randomCode.append(code);
        }
        // 將四位數字的驗證碼儲存到Session中。
        HttpSession session = req.getSession();
        System.out.print(randomCode);
        session.setAttribute("code", randomCode.toString());
 
        // 禁止影像快取。
        resp.setHeader("Pragma","no-cache");
        resp.setHeader("Cache-Control","no-cache");
        resp.setDateHeader("Expires",0);
 
        resp.setContentType("image/jpeg");
 
        // 將影像輸出到Servlet輸出流中。
        ServletOutputStream sos = resp.getOutputStream();
        ImageIO.write(buffImg,"jpeg", sos);
        sos.close();
    }
 
}


將UserController.java中add方法修改為下面這樣。

@RequestMapping("/user")
    publicModelAndView addUser(User user,HttpSession session) {
        ModelAndView mav=newModelAndView();
        if(!(user.getCode().equalsIgnoreCase(session.getAttribute("code").toString()))) {  //忽略驗證碼大小寫
            mav.setViewName("error");
            mav.addObject("msg","驗證碼不正確");
            returnmav;
        }else{
            user.setId(UUID.randomUUID().toString());
            user.setRegtime(newDate());
            try{
                userService.addUser(user);
            //  request.setAttribute("user", user);
                mav.setViewName("success");
                mav.addObject("user", user);
                mav.addObject("msg","註冊成功了,可以去登陸了");
                returnmav;
            }catch(Exception e) {
                mav.setViewName("menu");
                mav.addObject("user",null);
                mav.addObject("msg","註冊失敗");
                returnmav;
            }
        }
    }


然後就是修改前臺頁面了

將註冊的index.jsp的form修改

 <formaction="user.html"method="post">
 <tablewidth="207"border="0"align="center">
        <tr>
          <tdcolspan="2"align="center"nowrap="nowrap">使用者註冊</td>
        </tr>
        <tr>
          <tdwidth="68"nowrap="nowrap">使用者名稱</td>
          <tdwidth="127"nowrap="nowrap"><label>
            <inputname="username"type="text"id="username"size="20"/>
          </label></td>
        </tr>
        <tr>
          <tdnowrap="nowrap">密 碼</td>
          <tdnowrap="nowrap"><inputname="password"type="password"id="password"size="20"maxlength="10"/></td>
        </tr>
        <tr><td>驗證碼</td><td><inputid="index_code"name="code"type="text"/></td>
       <td> <imgid="imgObj"alt="驗證碼"src="code.html"/>
        <ahref="#"onclick="changeImg()">換一張</a></td></tr>
        <tr>
          <tdcolspan="2"align="center"nowrap="nowrap"><label>
            <inputtype="submit" value="註冊"/>
            <inputtype="reset" value="重填"/>
          </label></td>
        </tr>
  </table>
</form>


注意<img />標籤的src的寫法,寫成code.html。

其中用於實現“換一張”功能的javascript為下

<script type="text/javascript">
    functionchangeImg() {
        varimgSrc = $("#imgObj");
        varsrc = imgSrc.attr("src");
        imgSrc.attr("src", chgUrl(src));
    }
    //時間戳  
    //為了使每次生成圖片不一致,即不讓瀏覽器讀快取,所以需要加上時間戳  
    functionchgUrl(url) {
        vartimestamp = (newDate()).valueOf();
        url = url.substring(0, 17);
        if((url.indexOf("&") >= 0)) {
            url = url + "×tamp="+ timestamp;
        }else{
            url = url + "?timestamp="+ timestamp;
        }
        returnurl;
    }
</script>

?

其中,這一段js用到了jquery,別忘了在head中把jquery的js給引進來。

<scripttype="text/javascript"src="js/jquery-easyui-1.3.1/jquery-1.8.0.min.js"></script>

到此為止,一個完整的註冊程式就完成了。部署,測試,如圖

註冊成功瞭如下

驗證碼輸入錯誤,如下

然後就error了。。大笑

這個註冊的功能就基本完善了,當然,其實error的提示應該在原來的註冊頁面,可以使用ajax來實現,我只是寫示例程式,就沒那樣做了。追求完美的可以自己重構一下Controller的程式碼,返回json給瀏覽器,再用ajax實現不重新整理頁面,就可以實現真正的註冊功能了。
最後再囉嗦一句,需要這個demo專案原始碼的孩子,請聯絡郵箱sgl-2014@qq.com

或者去CSDN Code上去下載,地址:https://code.csdn.net/Sgl731524380/verificationcode/tree/master

相關文章