效果:

验证码还是没有布局好.背景比较怀古.

1.写前端html 
login.jsp

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1">
<title>登录</title>
<link rel="stylesheet" href="/static/css/layui.css">
<link rel="stylesheet" href="/static/css/login.css">
</head>
<body>
<div class="clear box layui-main login"> <form class="layui-form layui-form-pane1" action="ulogin" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户名:</label>
<div class="layui-input-block">
<input type="text" name="user.name" lay-verify="uname" required
placeholder="请输入用户名" autocomplete="off" class="layui-input">${UnameErrMsg?if_exists}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码:</label>
<div class="layui-input-block">
<input type="password" name="user.pwd" lay-verify="" required
placeholder="请输入密码" autocomplete="off" class="layui-input">${PwdErrMsg?if_exists}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">验证码:</label>
<div class="layui-input-block">
<input type="text" name="yzm" lay-verify="" required
placeholder="请输入验证码" autocomplete="off" class="layui-input">${yzmErrMsg?if_exists}<br>
<a href="/login.html"><img alt="验证码" src="/yzm"></a>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<button class="layui-btn layui-btn-normal btn-center" type="submit">登录</button>
</div>
</form>
</div> <script src="/static/js/layui.js"></script>
</body>
</html>

登录界面样式

@CHARSET "UTF-8";
body{
background-image:url(/static/images/login-bg.png);
}
.login {
padding-top: 15%;
width: 26%;
} .btn-center{
text-center:center;
margin:0 auto;
}

2.写控制器 
其中就是login方法与ulogin方法 
controller包下IndexController类

package cn.pangpython.controller;

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.ext.kit.SessionIdKit; import cn.pangpython.model.User;
import cn.pangpython.utils.DateUtils;
import cn.pangpython.utils.MD5;
import cn.pangpython.validate.RegistValidator;
import cn.pangpython.validate.UserLoginValidator; /**
* @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("注册成功!");
} public void login(){
render("login.html");
} @Before(UserLoginValidator.class)
public void ulogin(){
// 验证码结果
boolean result = validateCaptcha("yzm");
if (!result) {
setAttr("yzmErrMsg", "验证码错误!");
render("login.html");
return;
} String uname = getPara("user.name");
String sql = "select * from user where name = ? limit 1"; User user = User.dao.findFirst(sql, uname);
if (user != null) {
String pwd = MD5.GetMD5Code(getPara("user.pwd") + user.getRegTime()); if (user.getPwd().equals(pwd)) { // 生成唯一标识
String sessionId = SessionIdKit.me().generate(getRequest());
// 设置服务器端session
setSessionAttr(sessionId, user);
// 设置用户端cookie
setCookie("cuser", sessionId, 60000);
//redirect("/user");
renderText("登录成功!"); } else {
// 密码不正确
setAttr("UnameErrMsg", "用户名或密码不正确!");
render("login.html");
} } else {
// 用户名不存在
setAttr("UnameErrMsg", "用户名不存在!");
render("login.html");
} } }

3.写登录验证器 
validator包下的UserLoginValidator继承JFinal的Validator

package cn.pangpython.validate;

import com.jfinal.core.Controller;
import com.jfinal.validate.Validator; public class UserLoginValidator extends Validator { @Override
protected void handleError(Controller controller) {
controller.keepPara(); } @Override
protected void validate(Controller arg0) {
validateRequired("user.name", "UnameErrMsg", "请输入用户名!");
validateRequired("user.pwd", "PwdErrMsg", "请输入密码!");
validateRequired("yzm", "yzmErrMsg", "请输入验证码!");
} }

注:验证码的校验也可以在验证器中进行验证 
到此就完成了登录功能.运行config文件,访问

http://localhost/login

原文:https://blog.csdn.net/u012995856/article/details/52927053

JFinal Web开发学习(七)使用layUI美化的登录功能的更多相关文章

  1. JFinal Web开发学习(五)注册界面和后端验证

    效果: 直接点击注册后 : 后端验证是可靠地,前端js验证是不可靠的.只需要在浏览器删除js验证代码即可突破js验证. 1.注册界面 在WebRoot下新建regist.jsp <%@ page ...

  2. JFinal Web开发学习(一)开启HelloWorld

    初次接触JFinal框架,接触过MVC思想,接触过Spring. JFinal官网: http://www.jfinal.com/ 之前很嫌弃JavaWeb开发,主要原因是繁琐的xml配置. 官方推荐 ...

  3. JFinal Web开发学习(九)后台添加前台显示博客

    效果: 发博客: 显示博客: 后台:使用hui-admin,文章编辑器是百度开源的ueditor 前台:使用layui前端框架 1.写控制器BlogController controller包中 pa ...

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

    效果: 实现了注册界面的验证码验证.确认密码.密码md5加盐加密.C3P0插件数据库操作.读取外部配置文件. 1.在注册页面添加了确认密码输入框,修改了字段名称 <!DOCTYPE html&g ...

  5. JFinal Web开发学习(三)前后台路由设计

    效果图: 一.写控制器 1.在controller包中新建AdminController后台控制器,继承Controller,实现一个index方法,作为的处理方法. /admin 后面,这个控制器中 ...

  6. JFinal Web开发学习(八)后台集成H-ui-admin前端框架

    h-ui-admin是一个很不错的前端框架h-ui实现的一个后台管理系统的前端. 1.在WebRoot目录下新建admin目录 2.下载h-ui-admin(当前最新是2.5版本)并解压至admin文 ...

  7. JFinal Web开发学习(四)数据库连接与自动生成model

    1.新建数据库jfinal_test,user表 /* Navicat MySQL Data Transfer Source Server : . Source Server Version : 50 ...

  8. JFinal Web开发学习(二)目录、架构、package设计

    package分类 config是JFinal的项目配置 controller是控制器 handler可以设置全局处理器,例如判断用户请求中是否直接请求 FreeMarker的模板文件ftl或者htm ...

  9. 【前端】移动端Web开发学习笔记【2】 & flex布局

    上一篇:移动端Web开发学习笔记[1] meta标签 width设置的是layout viewport 的宽度 initial-scale=1.0 自带 width=device-width 最佳实践 ...

随机推荐

  1. mysql decimal

    可能做程序的人都知道,float类型是可以存浮点数(即小数类型),但是float有个坏处,当你给定的数据是整数的时候,那么它就以整数给你处理. 这样我们在存取货币值的时候自然遇到问题,我的defaul ...

  2. 【358】GitHub 上面文件夹下载方法

    参考:https://www.bilibili.com/read/cv210500/ 参考:https://www.jianshu.com/p/743ecc20ffb2 软件下载:Downloads ...

  3. Delphi动态调用C++写的DLL

    c++ DLL 文件,建议用最简单的c++编辑工具.不会加入很多无关的DLL文件.本人用codeblocks+mingw.不像 VS2010,DLL编译成功,调用的时候会提示缺其他DLL. 系统生成的 ...

  4. eclipse调试快捷键

    Eclipse中有如下一些和运行调试相关的快捷键. 1. [Ctrl+Shift+B]:在当前行设置断点或取消设置的断点.    2. [F11]:调试最后一次执行的程序.    3. [Ctrl+F ...

  5. centos 下安装redis

    一.安装redis 第一步:下载redis安装包 redis下载地址 wget http://download.redis.io/releases/redis-5.0.3.tar.gz 第二步:解压压 ...

  6. 使用pickle进行存储变量

    有时候我们需要把我们的变量内容存下来,这时我们就可以用pickle来操作. 存储操作如下所示: #!/usr/bin/python # -*- coding:utf-8 -*- import pick ...

  7. 如何跟踪某个session的SQL

    1 oracle自带的sql trace程序可以跟踪本地session sys: alter system set sql_trace = true;对所有会话跟踪 schema: alter ses ...

  8. 用JS和JQ来获取子节点!

    用JS和JQ来获取子节点!   在JS中,如果通过document.getElementsByTagName来获取子元素有个弊端:它不单会获取符合要求的子元素,就连同孙元素也会获取.如果有特殊要求,那 ...

  9. 关于Android file.createNewFile() 失败的问题

    [关于Android file.createNewFile() 失败的问题] 需要注意的是:要先对设计的文件路径创建文件夹 , 然后在对文件进行创建. 参考:http://blog.csdn.net/ ...

  10. msf客户端渗透(六):抓包、搜索文件、破解弱口令、修改MACE时间

    嗅探抓包 查看网卡 指定网卡,因为资源有限,默认抓满50000个包如果不dump下来,就会自动销毁掉,从0开始抓. dump嗅探到的文件到本机,传递到本机的过程是结果ssl加密的 dump了两个文件 ...