效果:
实现了注册界面的验证码验证、确认密码、密码md5加盐加密、C3P0插件数据库操作、读取外部配置文件.
代码地址:
https://code.csdn.net/u012995856/jfinaltest/tree/master
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 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());
}
}
3.在utils包中引入大牛写的两个工具类
一个是日期工具类,可以方便获取当前时间并转换成Unix时间戳
package cn.pangpython.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**
* 日期处理工具类
* @author jiang.li
* @date 2013-12-18 11:22
*/
public class DateUtils {
/**定义常量**/
public static final String DATE_FULL_STR = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_LONG_STR = "yyyy-MM-dd kk:mm:ss.SSS";
public static final String DATE_SMALL_STR = "yyyy-MM-dd";
public static final String DATE_KEY_STR = "yyMMddHHmmss";
public static final String DATE_All_KEY_STR = "yyyyMMddHHmmss";
/**
* 给指定的日期加上(减去)月份
* @param date
* @param pattern
* @param num
* @return
*/
public static String addMoth(Date date,String pattern,int num){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Calendar calender = Calendar.getInstance();
calender.setTime(date);
calender.add(Calendar.MONTH, num);
return simpleDateFormat.format(calender.getTime());
}
/**
* 给制定的时间加上(减去)天
* @param date
* @param pattern
* @param num
* @return
*/
public static String addDay(Date date,String pattern,int num){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Calendar calender = Calendar.getInstance();
calender.setTime(date);
calender.add(Calendar.DATE, num);
return simpleDateFormat.format(calender.getTime());
}
/**
* 获取系统当前时间
* @return
*/
public static String getNowTime() {
SimpleDateFormat df = new SimpleDateFormat(DATE_FULL_STR);
return df.format(new Date());
}
/**
* 获取系统当前时间(指定返回类型)
* @return
*/
public static String getNowTime(String type) {
SimpleDateFormat df = new SimpleDateFormat(type);
return df.format(new Date());
}
/**
* 使用预设格式提取字符串日期
* @param date 日期字符串
* @return
*/
public static Date parse(String date) {
return parse(date,DATE_FULL_STR);
}
/**
* 指定指定日期字符串
* @param date
* @param pattern
* @return
*/
public static Date parse(String date, String pattern) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
try {
return df.parse(date);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
/**
* 两个时间比较
* @param
* @return
*/
public static int compareDateWithNow(Date date){
Date now = new Date();
int rnum = date.compareTo(now);
return rnum;
}
/**
* 两个时间比较(时间戳比较)
* @param
* @return
*/
public static int compareDateWithNow(long date){
long now = dateToUnixTimestamp();
if(date>now){
return 1;
}else if(date<now){
return -1;
}else{
return 0;
}
}
/**
* 将指定的日期转换成Unix时间戳
* @param date 需要转换的日期 yyyy-MM-dd HH:mm:ss
* @return long 时间戳
*/
public static long dateToUnixTimestamp(String date) {
long timestamp = 0;
try {
timestamp = new SimpleDateFormat(DATE_FULL_STR).parse(date).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return timestamp;
}
/**
* 将指定的日期转换成Unix时间戳
* @param date 需要转换的日期 yyyy-MM-dd
* @return long 时间戳
*/
public static long dateToUnixTimestamp(String date, String dateFormat) {
long timestamp = 0;
try {
timestamp = new SimpleDateFormat(dateFormat).parse(date).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return timestamp;
}
/**
* 将当前日期转换成Unix时间戳
* @return long 时间戳
*/
public static long dateToUnixTimestamp() {
long timestamp = new Date().getTime();
return timestamp;
}
/**
* 将Unix时间戳转换成日期
* @param timestamp 时间戳
* @return String 日期字符串
*/
public static String unixTimestampToDate(long timestamp) {
SimpleDateFormat sd = new SimpleDateFormat(DATE_FULL_STR);
sd.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return sd.format(new Date(timestamp));
}
/**
* 将Unix时间戳转换成日期
* @param timestamp 时间戳
* @return String 日期字符串
*/
public static String TimeStamp2Date(long timestamp,String dateFormat){
String date = new SimpleDateFormat(dateFormat).format(new Date(timestamp));
return date;
}
/**
* 将Unix时间戳转换成日期
* @param timestamp 时间戳
* @return String 日期字符串
*/
public static String TimeStamp2Date(long timestamp){
String date = new SimpleDateFormat(DATE_FULL_STR).format(new Date(timestamp));
return date;
}
}
另一个是大牛写的MD5加密类,加密字符串可以是用户的密码混淆其他固定字符串(盐:salt).看过《Modern PHP》中作者说,千万不能知道用户的密码,即使是网站程序被脱裤了,解密出用户的密码需要他们付出高昂的代码也不一定能解出来才是好的.并且不要使用短信息或者邮件发送用户的明文密码.
package cn.pangpython.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**
* 日期处理工具类
* @author jiang.li
* @date 2013-12-18 11:22
*/
public class DateUtils {
/**定义常量**/
public static final String DATE_FULL_STR = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_LONG_STR = "yyyy-MM-dd kk:mm:ss.SSS";
public static final String DATE_SMALL_STR = "yyyy-MM-dd";
public static final String DATE_KEY_STR = "yyMMddHHmmss";
public static final String DATE_All_KEY_STR = "yyyyMMddHHmmss";
/**
* 给指定的日期加上(减去)月份
* @param date
* @param pattern
* @param num
* @return
*/
public static String addMoth(Date date,String pattern,int num){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Calendar calender = Calendar.getInstance();
calender.setTime(date);
calender.add(Calendar.MONTH, num);
return simpleDateFormat.format(calender.getTime());
}
/**
* 给制定的时间加上(减去)天
* @param date
* @param pattern
* @param num
* @return
*/
public static String addDay(Date date,String pattern,int num){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Calendar calender = Calendar.getInstance();
calender.setTime(date);
calender.add(Calendar.DATE, num);
return simpleDateFormat.format(calender.getTime());
}
/**
* 获取系统当前时间
* @return
*/
public static String getNowTime() {
SimpleDateFormat df = new SimpleDateFormat(DATE_FULL_STR);
return df.format(new Date());
}
/**
* 获取系统当前时间(指定返回类型)
* @return
*/
public static String getNowTime(String type) {
SimpleDateFormat df = new SimpleDateFormat(type);
return df.format(new Date());
}
/**
* 使用预设格式提取字符串日期
* @param date 日期字符串
* @return
*/
public static Date parse(String date) {
return parse(date,DATE_FULL_STR);
}
/**
* 指定指定日期字符串
* @param date
* @param pattern
* @return
*/
public static Date parse(String date, String pattern) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
try {
return df.parse(date);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
/**
* 两个时间比较
* @param
* @return
*/
public static int compareDateWithNow(Date date){
Date now = new Date();
int rnum = date.compareTo(now);
return rnum;
}
/**
* 两个时间比较(时间戳比较)
* @param
* @return
*/
public static int compareDateWithNow(long date){
long now = dateToUnixTimestamp();
if(date>now){
return 1;
}else if(date<now){
return -1;
}else{
return 0;
}
}
/**
* 将指定的日期转换成Unix时间戳
* @param date 需要转换的日期 yyyy-MM-dd HH:mm:ss
* @return long 时间戳
*/
public static long dateToUnixTimestamp(String date) {
long timestamp = 0;
try {
timestamp = new SimpleDateFormat(DATE_FULL_STR).parse(date).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return timestamp;
}
/**
* 将指定的日期转换成Unix时间戳
* @param date 需要转换的日期 yyyy-MM-dd
* @return long 时间戳
*/
public static long dateToUnixTimestamp(String date, String dateFormat) {
long timestamp = 0;
try {
timestamp = new SimpleDateFormat(dateFormat).parse(date).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return timestamp;
}
/**
* 将当前日期转换成Unix时间戳
* @return long 时间戳
*/
public static long dateToUnixTimestamp() {
long timestamp = new Date().getTime();
return timestamp;
}
/**
* 将Unix时间戳转换成日期
* @param timestamp 时间戳
* @return String 日期字符串
*/
public static String unixTimestampToDate(long timestamp) {
SimpleDateFormat sd = new SimpleDateFormat(DATE_FULL_STR);
sd.setTimeZone(TimeZone.getTimeZone("GMT+8"));
return sd.format(new Date(timestamp));
}
/**
* 将Unix时间戳转换成日期
* @param timestamp 时间戳
* @return String 日期字符串
*/
public static String TimeStamp2Date(long timestamp,String dateFormat){
String date = new SimpleDateFormat(dateFormat).format(new Date(timestamp));
return date;
}
/**
* 将Unix时间戳转换成日期
* @param timestamp 时间戳
* @return String 日期字符串
*/
public static String TimeStamp2Date(long timestamp){
String date = new SimpleDateFormat(DATE_FULL_STR).format(new Date(timestamp));
return date;
}
}
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("注册成功!");
}
}
打完收工!