1. 程式人生 > >JFinal Web開發學習(六)驗證碼驗證和註冊細節

JFinal Web開發學習(六)驗證碼驗證和註冊細節

inpu tin ins print cap instance amp 填充 time

效果:

技術分享圖片

技術分享圖片

技術分享圖片

實現了註冊界面的驗證碼驗證、確認密碼、密碼md5加鹽加密、C3P0插件數據庫操作、讀取外部配置文件.

1.在註冊頁面添加了確認密碼輸入框,修改了字段名稱

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>註冊</title>
</head>
<body>
<form action="regist" method="POST">
用戶名:<input name="user.name" type="text"
>${nameErrMsg!}<br><br> 密碼: <input name="user.pwd" type="password">${pwdErrMsg!}<br><br> 確認密碼: <input name="reg.confirm" type="password">${confirmErrMsg!}<br><br> 驗證碼:<input type="text" name="reg.yzm"><img src="/yzm"><br><br>
${yzmErrMsg!} <button type="submit"> 註冊</button> </form> </body> </html>

2.在配置類中添加C3P0插件配置
在config包中MyJFinalConfig類中添加C3P0插件的代碼

package cn.pangpython.config;

import javax.print.attribute.standard.Media;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors; import com.jfinal.config.JFinalConfig; import com.jfinal.config.Plugins; import com.jfinal.config.Routes; import com.jfinal.kit.PropKit; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; import com.jfinal.plugin.c3p0.C3p0Plugin; import com.jfinal.render.ViewType; import cn.jfinal.model._MappingKit; import cn.jfinal.routes.AdminRoutes; import cn.jfinal.routes.FrontRoutes; public class MyJFinalConfig extends JFinalConfig { @Override public void configConstant(Constants me) { // 開發模式 me.setDevMode(true); //這裏可以通過配置文件來讀取配置參數,更靈活 PropKit.use("SystemConfig.txt"); //指定視圖 me.setViewType(ViewType.JSP); } @Override public void configHandler(Handlers arg0) { // 這裏可以配置全局處理器,放置直接訪問模板文件暴露數據庫表和字段 } @Override public void configInterceptor(Interceptors arg0) { // 這裏可以配置攔截器進行權限管理 } @Override public void configPlugin(Plugins me) { // 這裏可以配置Jfinal的各種插件,比如數據庫插件等 C3p0Plugin c3p0Plugin=createC3p0Plugin(); me.add(c3p0Plugin); ActiveRecordPlugin arp=new ActiveRecordPlugin(c3p0Plugin); me.add(arp); _MappingKit.mapping(arp); } @Override public void configRoute(Routes me) { //這裏是配置url由控制器來響應這個請求 //添加前臺路由 me.add(new FrontRoutes()); //添加後臺路由 me.add(new AdminRoutes()); } //通過讀取外部配置文件參數創建C3p0插件 public static C3p0Plugin createC3p0Plugin() { return new C3p0Plugin(PropKit.get("jdbcUrl"),PropKit.get("user"),PropKit.get("password").trim()); } }

3.在utils包中引入大牛寫的兩個工具類
一個是日期工具類,可以方便獲取當前時間並轉換成Unix時間戳

package cn.pangpython.config;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.JFinal;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.c3p0.C3p0Plugin;

import cn.pangpython.model._MappingKit;
import cn.pangpython.routes.AdminRoutes;
import cn.pangpython.routes.FrontRoutes;


/**
 * @author pangPython
 *  JFinal 項目配置文件
 */

public class MyJFinalConfig extends JFinalConfig {

    @Override
    public void configConstant(Constants me) {
        //開啟開發模式
        me.setDevMode(true);
        //這裏可以通過配置文件來讀取配置參數,更靈活
        PropKit.use("SystemConfig.txt");
    }

    @Override
    public void configRoute(Routes me) {
        //添加前臺路由
        me.add(new FrontRoutes());
        //添加後臺路由
        me.add(new AdminRoutes());
    }

    @Override
    public void configHandler(Handlers arg0) {
        // 這裏可以配置全局處理器 防止直接訪問模板文件暴露數據庫表和字段      
    }

    @Override
    public void configInterceptor(Interceptors arg0) {
        // 這裏可以配置攔截器進項權限管理      
    }

    @Override
    public void configPlugin(Plugins me) {
        // 這裏可以配置JFinal的各種插件,比如數據庫插件等

        C3p0Plugin c3p0Plugin = createC3p0Plugin();
        me.add(c3p0Plugin);
        ActiveRecordPlugin arp = new ActiveRecordPlugin(c3p0Plugin);
        me.add(arp);
        _MappingKit.mapping(arp);

    }

    //使用JFinal內置的jetty啟動項目,直接作為java application運行此文件
    public static void main(String[] args) {
        JFinal.start("WebRoot", 80, "/", 5);
    }

    //通過讀取外部配置文件參數創建C3P0插件
    public static C3p0Plugin createC3p0Plugin(){
        return new C3p0Plugin(PropKit.get("jdbcUrl"),PropKit.get("user"),PropKit.get("password").trim());
    }

}

另一個是大牛寫的MD5加密類,加密字符串可以是用戶的密碼混淆其他固定字符串(鹽:salt).看過《Modern PHP》中作者說,千萬不能知道用戶的密碼,即使是網站程序被脫褲了,解密出用戶的密碼需要他們付出高昂的代碼也不一定能解出來才是好的.並且不要使用短信息或者郵件發送用戶的明文密碼.

package cn.pangpython.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {

    // 全局數組
    private final static String[] strDigits = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
 
    public MD5() {
        
    }
 
    // 返回形式為數字跟字符串
    private static String byteToArrayString(byte bByte) {
        int iRet = bByte;
        // System.out.println("iRet="+iRet);
        if (iRet < 0) {
            iRet += 256;
        }
        int iD1 = iRet / 16;
        int iD2 = iRet % 16;
        return strDigits[iD1] + strDigits[iD2];
    }
 
    // 返回形式只為數字
    private static String byteToNum(byte bByte) {
        int iRet = bByte;
        System.out.println("iRet1=" + iRet);
        if (iRet < 0) {
            iRet += 256;
        }
        return String.valueOf(iRet);
    }
 
    // 轉換字節數組為16進制字串
    private static String byteToString(byte[] bByte) {
        StringBuffer sBuffer = new StringBuffer();
        for (int i = 0; i < bByte.length; i++) {
            sBuffer.append(byteToArrayString(bByte[i]));
        }
        return sBuffer.toString();
    }
 
    public static String GetMD5Code(String strObj) {
        String resultString = null;
        try {
            resultString = new String(strObj);
            MessageDigest md = MessageDigest.getInstance("MD5");
            // md.digest() 該函數返回值為存放哈希值結果的byte數組
            resultString = byteToString(md.digest(strObj.getBytes()));
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return resultString;
    }
 
    public static void main(String[] args) {
        MD5 getMD5 = new MD5();
        System.out.println(getMD5.GetMD5Code("000000"));
    }


}

4.在註冊驗證器中添加確認密碼的為空驗證

package cn.pangpython.validate;

import com.jfinal.core.Controller;
import com.jfinal.validate.Validator;

/**
 * @author pangPython
 *  註冊的驗證器
 */
public class RegistValidator extends Validator {

    @Override
    protected void handleError(Controller arg0) {

    }

    @Override
    protected void validate(Controller arg0) {
        validateRequired("user.name", "nameErrMsg", "請填寫用戶名!");
        validateRequired("user.pwd", "pwdErrMsg", "請填寫密碼!");
        validateRequired("reg.confirm", "confirmErrMsg", "請填寫確認密碼!");
        validateRequired("reg.yzm", "yzmErrMsg", "請填寫驗證碼!");
    }

}

5.<正題….>寫控制器中的註冊功能的邏輯
其中涉及到Jfinal的驗證碼校驗、model的快速數據庫操作方法

package cn.pangpython.controller;

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;

import cn.pangpython.model.User;
import cn.pangpython.utils.DateUtils;
import cn.pangpython.utils.MD5;
import cn.pangpython.validate.RegistValidator;

/**
 * @author pangPython
 * 主頁控制器
 */
public class IndexController extends Controller {
    public void index(){
        renderText("index");
    }

    //渲染註冊頁面
    public void regpage(){
        render("regist.html");
    }

    //處理註冊
    @Before(RegistValidator.class)
    public void regist(){
        String pwd = getPara("user.pwd");
        String confirm = getPara("reg.confirm");

        //驗證碼驗證
        boolean result = validateCaptcha("reg.yzm");
        if(!result){
            setAttr("yzmErrMsg", "驗證碼錯誤!");
            render("regist.html");
            return;
        }
        //確認密碼驗證
        if(!pwd.equals(confirm)){
            setAttr("confirmErrMsg", "請正確填寫確認密碼!");
            render("regist.html");
            return;
        }

        String uname = getPara("user.name");
        User user = getModel(User.class);
        String reg_time = DateUtils.dateToUnixTimestamp(DateUtils.getNowTime())+"";
        //使用用戶註冊日期作為md5密碼加密的鹽值,可節省一個salt數據庫字段
        pwd = MD5.GetMD5Code(pwd+reg_time);

        //給user實體類填充數據
        user.setName(uname);
        user.setPwd(pwd);
        user.setRegTime(reg_time);

        //使用jfinal的保存操作
        user.save();

        renderText("註冊成功!");
    }

}

打完收工!

: )


參考原文:https://blog.csdn.net/u012995856/article/details/52863489

JFinal Web開發學習(六)驗證碼驗證和註冊細節