登录+验证码(maven+servlet实现)

本文介绍了一种使用Maven构建的Java Web应用中,通过Servlet实现登录页面(login.jsp)与验证码功能的方法。包括CheckCodeServlet用于生成验证码,UserServlet处理用户登录请求,业务层和持久层实现数据交互,BaseDao和DBHelper提供数据库操作支持,JsonData和PrintJsonData用于返回JSON数据,展示登录验证的整个流程和最终效果。
部署运行你感兴趣的模型镜像

login.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>用户登录</title>
    <meta name="description" content="particles.js is a lightweight JavaScript library for creating particles.">
    <meta name="author" content="Vincent Garreau" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <link rel="stylesheet" media="screen" href="static/css/style.css">
    <link rel="stylesheet" type="text/css" href="static/css/reset.css"/>
    <link rel="stylesheet" type="text/css" href="static/layui/css/layui.css"/>
</head>
<body>

<div id="particles-js">
    <form class="login layui-form">
        <div class="login-top">
            登录
        </div>
        <div class="login-center clearfix">
            <!--隐藏的属性 ,默认值是 登录-->
            <input type="hidden" name="service" value="login" />
            <div class="login-center-img"><img src="static/img/name.png"/></div>
            <div class="login-center-input">
                <input type="text" value="abc" name="user_name"  placeholder="用户名" onfocus="this.placeholder=''" onblur="this.placeholder='请输入您的用户名'"/>
                <div class="login-center-input-text">用户名</div>
            </div>
        </div>
        <div class="login-center clearfix">
            <div class="login-center-img"><img src="static/img/password.png"/></div>
            <div class="login-center-input">
                <input type="password" value="abc" name="password" placeholder="用户密码" onfocus="this.placeholder=''" onblur="this.placeholder='请输入您的密码'"/>
                <div class="login-center-input-text">密码</div>
            </div>
        </div>
        <div class="login-center clearfix">
            <div class="login-center-img"><img src="static/img/password.png"/></div>
            <div class="login-center-input">
                <input type="text" name="checkCode" placeholder="验证码"  style="width: 130px"/>
                <div class="login-center-input-text">验证码</div>
                <img id="checkCode" alt="验证码" src="checkCode" style="width: 70px;margin-left: 20px">
            </div>
        </div>
        <div class="login-button" lay-submit lay-filter="loginBtnFilter">
            登录
        </div>
    </form>
    <div class="sk-rotating-plane"></div>
</div>
<div style="text-align:center;">
</div>
<!-- scripts -->
<script src="static/layui/layui.js"></script>
<!--引入登录页 "星空粒子" js-->
<script src="static/js/particles.min.js"></script>
<!--登录页调整星空粒子间隔,坐标...-->
<script src="static/js/app.js"></script>
<script type="text/javascript">

    //登录页面用到的 layui组件,有表单,弹层,jquery
    layui.use(['form','layer','jquery'],function () {
        var form = layui.form;  //获取表单对象
        var layer = layui.layer;//获取弹出层对象
        var $ = layui.jquery;//获取layui内置的jquery对象
        //提交登陆表单
        form.on('submit(loginBtnFilter)',function (d) {
            // d.field 等于 {key:value,key:value...}
            $.post('user',d.field,function (rs) {    //jquery的异步提交
                if(rs.code==200){   //如果响应成功,则进入主页面
                    location.href='page?page=main';//PageServlet 负责管理页面跳转
                    return false;//终止执行
                }
                //弹出层的提示信息
                layer.msg(rs.msg);
                //如果验证码输入错误  再次刷新验证码 根据时间进行提交  防止上一次的验证码缓存
                $("#checkCode").prop("src","checkCode"+"?"+new Date());
            },"json");
            return false;   //组织表单名默认提交
        });

        //点击验证码进行切换
        $("#checkCode").click(function(){
            // 给 img对象的 src属性 ,重新赋值checkCode , 时间防止缓存
            $(this).attr("src","checkCode?"+new Date());
        });
    });

</script>
</body>
</html>

CheckCodeServlet:

@WebServlet("/checkCode")
public class CheckCodeServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //拿到 验证码工具类对象
        CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(110, 40, 4, 6);
        String code = circleCaptcha.getCode();//取出 4个字符
        //将图片写出去
        //将code 存入session
        req.getSession().setAttribute("code",code);
        circleCaptcha.write(resp.getOutputStream());
        //resp.getWriter().print(image);
    }
}

UserServlet:

@WebServlet("/user")
public class UserServlet extends HttpServlet {
    UserService userService=new UserServiceImpl();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String service = req.getParameter("service");
        try {
            this.getClass().getDeclaredMethod(service,HttpServletRequest.class,HttpServletResponse.class).invoke(this,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 登录
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取参数
        String user_name = req.getParameter("user_name");
        String password = req.getParameter("password");
        String checkCode = req.getParameter("checkCode");
        String str = (String) req.getSession().getAttribute("code");
        //判断前台输入的checkCode是否和session里面的str一样
        if(!StrUtil.equalsIgnoreCase(checkCode,str)){
            JsonData jsonData = JsonData.buildError("验证码错误");
            PrintJsonData.print(resp,jsonData);
            return ;
        }
        //调取业务层,执行登陆
        JsonData jsonData=userService.login(user_name,password);
        if (jsonData.getData()!=null){
            User user= (User) jsonData.getData();
            req.getSession().setAttribute("user",user);
        }
        //将数据返回到页面
        PrintJsonData.print(resp,jsonData);
    }

业务层:

public class UserServiceImpl implements UserService {
    UserDao userDao = new UserDaoImpl();

    public JsonData login(String user_name, String password) {
        User user = userDao.login(user_name, password);
        if (user == null) {
            return JsonData.buildError("用户名或密码有误");
        }
        if (user.getIs_del() == 2) {
            return JsonData.buildError("当前用户不可用");
        }
        return JsonData.buildSuc(user);
    }
    }

持久层:

public class UserDaoImpl extends BaseDao implements UserDao {
    public User login(String user_name, String password) {
        String sql="select * from t_user where user_name=? and password=?";
        return super.findOne(sql,User.class,user_name,password);
    }
    }

BaseDao:

/**
 * 父类 封装jdbc
 * 泛型: 第一种写到类名后面 比如: BaseDao<T>
 *     第2中写到方法名中 public <T> T test(){}
 */
public class BaseDao {

    /**
     * 通过结果集 rs 给 clz对象 中的属性赋值
     * @param rs
     * @param clz
     * @param <T>
     * @return
     */
    private <T> T rsToBean(ResultSet rs, Class<T> clz) {
        try {
            T t = clz.newInstance();    //通过反射拿到一个 类的实例 ,当前类可能是User ,或者是别的类
            // 从rs 取值 ,赋值到 t中的 成员变量
            ResultSetMetaData metaData = rs.getMetaData();  //获取当前表的 元数据  (表的结构信息)
            int columnCount = metaData.getColumnCount();    //拿到列的总数量
            for (int i = 0; i < columnCount; i++) {
                String columnLabel = metaData.getColumnLabel(i + 1);//拿到 表中 列的名称 ,比如: id  user_name/ password/ create_time.....
                //user.setId(rs.getInt("id"));      rs.getInt("id")===rs.getObject(columnLabel)
                Object value = rs.getObject(columnLabel);   //取出列名  对应的值
                // getDeclaredField() 拿到当前类所有属性
                Field field = clz.getDeclaredField(columnLabel);    //根据 列名 拿到 类对应的 属性名 ,比如:id  user_name/ password/ create_time
                field.setAccessible(true);  //提高 反射 效率
                //赋值
                field.set(t,value); //
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 查询单个对象
     * @param sql
     * @param clz
     * @param param
     * @param <T>
     * @return
     */
    public <T> T findOne(String sql,Class<T> clz,Object...param){
        List<T> list = findList(sql, clz, param);
        if(list!=null&&list.size()==1){
            return list.get(0);
        }
        return null;
    }

DBHelper:

public class DBHelper {

    //1. 拿到 druid 的数据源
    static DruidDataSource dataSource;
    //2. 读取配置文件 ,初始化数据源
    static {
        Properties properties = new Properties();
        InputStream is = DBHelper.class.getClassLoader().getResourceAsStream("jdbc.properties");

        try {
            properties.load(is);
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //3. 拿到数据库连接对象
    public static Connection getConnection(){
        try {
            DruidPooledConnection conn = dataSource.getConnection();
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    //4. 资源释放  (适用于增删改)
    public static void close(Connection conn, PreparedStatement ps){
        try {
            if(conn!=null){
                conn.close();
            }
            if(ps!=null){
                ps.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(Connection conn, PreparedStatement ps, ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
           close(conn,ps);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(getConnection());
    }
}

JsonData:

/**
 * 封装 , 返回json的数据样式
 */
public class JsonData {

    private Integer code;       //响应码
    private String msg; //描述信息
    private Object data;    //响应的数据

    public JsonData(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static JsonData buildSuc(String msg, Object data){
        return new JsonData(200,msg,data);
    }

    public static JsonData buildSuc(Object data){
        return new JsonData(200,null,data);
    }

    public static JsonData buildSuc(String msg){
        return new JsonData(200,msg,null);
    }

    public static JsonData buildError(String msg){
        return new JsonData(50000,msg,null);
    }

    public static JsonData buildSuc() {
        return new JsonData(200,null,null);
    }


    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

PrintJsonData:

public class PrintJsonData {

    public static void print(HttpServletResponse resp,JsonData jsonData){
        resp.setContentType("text/html;charset=UTF-8");
        String json = JSON.toJSONString(jsonData);
        PrintWriter pw = null;
        try {
            pw = resp.getWriter();
            pw.print(json);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

效果展示:
效果图

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值