JFinal Web开发学习(六)验证码验证和注册细节

效果:

JFinal Web开发学习(六)验证码验证和注册细节

JFinal Web开发学习(六)验证码验证和注册细节

JFinal Web开发学习(六)验证码验证和注册细节

实现了注册界面验证码验证、确认密码、密码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

上一篇:Spring Boot -- 启动流程分析之ApplicationContext 中


下一篇:PHP页面跳转到另一个页面的方法