Java-web实现用户登录、注册功能

news2025/1/21 5:49:04

目录

  • 环境搭建
    • 数据库
  • 用户登录
    • 需求分析
    • 代码实现
      • 编写UserMapper类
      • 编写User类
      • 编写loginServlet类
      • 编写login.html
      • 编写login.css
  • 用户注册
    • 需求分析
    • 代码编写
      • 编写UserMapper类
      • 编写registerServlet类
      • 编写register.html
      • 编写register.css
  • 编写SqlSessionFactory工具类
  • 项目总体架构
  • 运行展示
  • 案例图片

环境搭建

在编写代码之前,在pom.xml导入servlet、mybatis的依赖,导入tomcat插件。
在这里插入图片描述

数据库

在这里插入图片描述

用户登录

需求分析

  1. 在前端页面输入用户名和密码,点击登录,将数据提交给servlet。
  2. 在servlet中编写程序,实现接收前端提交的用户名和密码。
  3. 在servlet中通过Mybatis框架调用Mapper查询,返回结果封装成一个User对象并返回
  4. 判断User对象是否为null,是null登录失败、不是null登录成功。

代码实现

编写UserMapper类

编写UserMapper提供根据用户名、密码查询用户数据方法方法

public interface UserMapper {

    /**
     *根据用户名 密码 查询用户
     * @param username
     * @param password
     * @return
     */
    @Select("select* from tb_user where username =#{username} and password = #{password}")
    User select(@Param("username") String username, @Param("password") String password);


}

编写User类

编写User类

public class User {
    private Integer id;
    private String username;
    private String password;

    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

}

编写loginServlet类

编写loginServlet类

@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //第一步:接收用户名、密码

        String username;
        username= req.getParameter("username");
        String password;
        password= req.getParameter("password");
        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        username = new String(bytes, StandardCharsets.UTF_8);
        byte[] bytes1 = password.getBytes(StandardCharsets.ISO_8859_1);
        password = new String(bytes1, StandardCharsets.UTF_8);
        //第二步:调用Mybatis查询用户
        //工具类SqlSessionFactoryUtil调用方法返回sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
        //  获取sqlSession对象,执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取UserMapper接口的代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //获取方法
        User user = mapper.select(username, password);
        sqlSession.close();
        //获取字符的输出流 设置content-type
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        //第三步:判断
        if(user!=null){
            //登陆成功
            writer.write("登录成功");
        }else {
            //登录失败
            writer.write("登录失败");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        this.doGet(req, resp);
    }
}

编写login.html

编写login.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>login</title>
    <link href="css/login.css" rel="stylesheet">
</head>

<body>
<div id="loginDiv">
    <form action="/Web-Demo/loginServlet" method="post" id="form">
        <h1 id="loginMsg">LOGIN IN</h1>
        <p>UserName:<input id="username" name="username" type="text"></p>

        <p>PassWord:<input id="password" name="password" type="password"></p>

        <div id="subDiv">
            <input type="submit" class="button" value="login up">
            <input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;
            <a href="register.html">没有账号?点击注册</a>
        </div>
    </form>
</div>
</body>
</html>

编写login.css

编写login.css

* {
    margin: 0;
    padding: 0;
}

html {
    height: 100%;
    width: 100%;
    overflow: hidden;
    margin: 0;
    padding: 0;
    background: url(../imgs/BackGround.JPG) no-repeat 0px 0px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    -moz-background-size: 100% 100%;
}

body {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
}

#loginDiv {
    width: 37%;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 300px;
    background-color: rgba(75, 81, 95, 0.3);
    box-shadow: 7px 7px 17px rgba(52, 56, 66, 0.5);
    border-radius: 5px;
}

#name_trip {
    margin-left: 50px;
    color: red;
}

p {
    margin-top: 30px;
    margin-left: 20px;
    color: azure;
}

input {
    margin-left: 15px;
    border-radius: 5px;
    border-style: hidden;
    height: 30px;
    width: 140px;
    background-color: rgba(216, 191, 216, 0.5);
    outline: none;
    color: #f0edf3;
    padding-left: 10px;
}
#username{
    width: 200px;
}
#password{
    width: 202px;
}
.button {
    border-color: cornsilk;
    background-color: rgba(100, 149, 237, .7);
    color: aliceblue;
    border-style: hidden;
    border-radius: 5px;
    width: 100px;
    height: 31px;
    font-size: 16px;
}

#subDiv {
    text-align: center;
    margin-top: 30px;
}
#loginMsg{
    text-align: center;color: aliceblue;
}

用户注册

需求分析

  1. 在前端页面输入用户名和密码,点击注册,将数据提交给servlet。
  2. 在servlet中编写程序,实现接收前端提交的用户名和密码。
  3. 在servlet中通过Mybatis框架调用Mapper查询,返回结果封装成一个User对象并返回
  4. 判断User对象是否为null,是null调用mapper添加用户、不是null代表用户已存在。

代码编写

编写UserMapper类

编写UserMapper提供根据用户名查询用户数据方法和添加用户方法

public interface UserMapper {
    /**
     * 根据用户名查询用户对象
     * @param username
     * @return
     */
    @Select("select* from tb_user where username =#{username}")
    User selectByUsername(String username);

    /**
     * 添加用户
     */
    @Select("insert into tb_user values(null,#{username},#{password})")
    void add(User user);
}

编写registerServlet类

@WebServlet("/registerServlet")
public class registerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //第一步:接收用户名、密码

        String username;
        String password;
        username= req.getParameter("username");
        password= req.getParameter("password");


        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        username = new String(bytes, StandardCharsets.UTF_8);
        byte[] bytes1 = password.getBytes(StandardCharsets.ISO_8859_1);
        password = new String(bytes1, StandardCharsets.UTF_8);
        //封装用户对象
        User user1 = new User();
        user1.setUsername(username);
        user1.setPassword(password);


        //第二步:调用Mybatis查询用户
        //加载Mybatis的核心配置文件
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
        //  获取sqlSession对象,执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取UserMapper接口的代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //获取方法
        User user = mapper.selectByUsername(username);


        //获取字符的输出流 设置content-type
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        //第三步:判断
        if(user==null){
            //用户名不存在,添加用户
            mapper.add(user1);
            //提交事务
            sqlSession.commit();
            sqlSession.close();
        }else {
            //用户存在,给出提示信息
            writer.write("用户已存在");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        this.doGet(req, resp);
    }
}

编写register.html

采用正则表达式实现用户名不超过15个字符、密码在4~10个字符。采用上个案例的注册界面。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>欢迎注册</title>
    <link rel = "stylesheet" href="css/register.css">
</head>
<body>
<div class = "form-div">
    <div class="reg-content">
        <h1>欢迎注册</h1>
        <span>已有账号?</span>
        <a href="login.html">登录</a>
    </div>
    <form id = "reg-form" action="/Web-Demo/registerServlet" method="post">
        <table>
            <tr>
                <td>用户名:</td>
                <td class="inputs">
                    <input type="text" name = "username" id="username"/>
                    <br>
                    <span id = "username_err" class="err_msg" style="display:none">用户名不符合规则</span>
                </td>
            </tr>
            <tr>
                <td>密码:</td>
                <td class="inputs">
                    <input type="password" name = "password" id = "password"/>
                    <br>
                    <span id="password_err" class="err_msg" style="display: none">密码格式有误</span>
                </td>
            </tr>

        </table>
        <div class="buttons">
            <input type = "submit" value="注册" id ="reg_btn" />
        </div>
        <br class="clear">
    </form>
</div>
<script>

    //验证用户名
    var usernameInput = document.getElementById("username");
    usernameInput.onblur = checkUser;
    function checkUser(){
        var username = usernameInput.value.trim();
        //判断用户名是否符合规则:长度0~15 单词字符组成
        var reg = /^\w{0,15}$/;
        var flag= reg.test(username);
        if(flag){
            document.getElementById("username_err").style.display = "none";
        }else{
            document.getElementById("username_err").style.display = "";
        }
        return flag;
    }
    //验证密码
    var passwordInput = document.getElementById("password");
    passwordInput.onblur = checkPassword;
    function checkPassword(){
        var password = passwordInput.value.trim();
        var reg = /^\w{4,10}$/;
        var flag= reg.test(password);
        if(flag){
            document.getElementById("password_err").style.display = "none";
        }else{
            document.getElementById("password_err").style.display = "";
        }
        return flag;
    }
</script>
</body>
</html>

编写register.css

* {
    margin: 0;
    padding: 0;
    list-style-type: none;
}
.reg-content{
    padding: 30px;
    margin: 3px;
}
a, img {
    border: 0;
}

body {
    background-image: url("../imgs/BackGround.JPG") ;
    no-repeat:center center fixed;
    /*兼容浏览器版本*/
    -webkit-background-size: cover;
    -o-background-size: cover;
    background-size: cover;

    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
}

table {
    border-collapse: collapse;
    border-spacing: 0;
}

td, th {
    padding: 0;
    height: 90px;

}
.inputs{
    vertical-align: top;
}

.clear {
    clear: both;
}

.clear:before, .clear:after {
    content: "";
    display: table;
}

.clear:after {
    clear: both;
}

.form-div {
    background-color: rgba(255, 255, 255, 0.27);
    border-radius: 10px;
    border: 1px solid #aaa;
    width: 424px;
    margin-top: 150px;
    margin-left:1050px;
    padding: 30px 0 20px 0px;
    font-size: 16px;
    box-shadow: inset 0px 0px 10px rgba(255, 255, 255, 0.5), 0px 0px 15px rgba(75, 75, 75, 0.3);
    text-align: left;
}

.form-div input[type="text"], .form-div input[type="password"], .form-div input[type="email"] {
    width: 268px;
    margin: 10px;
    line-height: 20px;
    font-size: 16px;
}

.form-div input[type="checkbox"] {
    margin: 20px 0 20px 10px;
}

.form-div input[type="button"], .form-div input[type="submit"] {
    margin: 10px 20px 0 0;
}

.form-div table {
    margin: 0 auto;
    text-align: right;
    color: rgba(64, 64, 64, 1.00);
}

.form-div table img {
    vertical-align: middle;
    margin: 0 0 5px 0;
}

.footer {
    color: rgba(64, 64, 64, 1.00);
    font-size: 12px;
    margin-top: 30px;
}

.form-div .buttons {
    float: right;
}

input[type="text"], input[type="password"], input[type="email"] {
    border-radius: 8px;
    box-shadow: inset 0 2px 5px #eee;
    padding: 10px;
    border: 1px solid #D4D4D4;
    color: #333333;
    margin-top: 5px;
}

input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus {
    border: 1px solid #50afeb;
    outline: none;
}

input[type="button"], input[type="submit"] {
    padding: 7px 15px;
    background-color: #3c6db0;
    text-align: center;
    border-radius: 5px;
    overflow: hidden;
    min-width: 80px;
    border: none;
    color: #FFF;
    box-shadow: 1px 1px 1px rgba(75, 75, 75, 0.3);
}

input[type="button"]:hover, input[type="submit"]:hover {
    background-color: #5a88c8;
}

input[type="button"]:active, input[type="submit"]:active {
    background-color: #5a88c8;
}
.err_msg{
    color: red;
    padding-right: 170px;
}
#password_err,#tel_err{
    padding-right: 195px;
}

#reg_btn{
    margin-right:50px; width: 285px; height: 45px; margin-top:20px;
}

编写SqlSessionFactory工具类

在写Servlet的时候,因为需要使用Mybatis来完成数据库的操作,所
以对于Mybatis的基础操作就出现了些重复代码:

String resource = "mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

SqlSessionFactory sqlSessionFactory = new 
 SqlSessionFactoryBuilder().build(inputStream);

有了这些重复代码就会造成一些问题:

  1. 重复代码不利于后期的维护

  2. SqlSessionFactory工厂类进行重复创建,资源消耗非常大但性能却非常低。

  3. 代码重复可以抽取工具类

  4. 对指定代码只需要执行一次可以使用静态代码块

对于静态代码块会随着类的加载而自动执行同时加载,只执行一次,就很好解决这一问题。

public class SqlSessionFactoryUtil {
//SqlSessionFactory工具类抽取
    private static SqlSessionFactory sqlSessionFactory;
    static {
        //静态代码块会随着类的加载而加载 只执行一次

        //加载Mybatis的核心配置文件
        String resource = "mybatis-config.xml";
        InputStream resourceAsStream = null;
        try {
            resourceAsStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //  获取sqlSessionFactory对象
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
   }
    public static SqlSessionFactory getSqlSessionFactory (){

        return sqlSessionFactory;
    }
}

工具类抽取以后,以后在对Mybatis的SqlSession进行操作的时候,就可以直接使用。

项目总体架构

在这里插入图片描述

运行展示

用户登录:
在这里插入图片描述

登录成功:
在这里插入图片描述
来一个登录失败的案例:admin用户不存在
在这里插入图片描述

登录失败:

在这里插入图片描述

注册admin用户:
在这里插入图片描述

注册成功,后端数据库已写入admin用户数据

在这里插入图片描述

案例图片

漂亮~~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

css绘制一个Pinia小菠萝

效果如下&#xff1a; pinia小菠萝分为头部和身体&#xff0c;头部三片叶子&#xff0c;菠萝为身体 头部 先绘制头部的盒子&#xff0c;将三片叶子至于头部盒子中 先绘制中间的叶子&#xff0c;利用border-radius实现叶子的效果&#xff0c;可以借助工具来快速实现圆角的预想…

SpringBoot 单元测试——JUnit5

目录 1、JUnit5概述 1.1、JUnit5 构成 1.2、JUnit5 配置 1.2.1、导入 Junit5 开发场景 1.2.2、Junit5 开发场景自动导入依赖项 2、JUnit5 使用 2.1、Jnuit5 测试代码开发 2.1.1、测试代码格式 2.1.2、测试样例 2.2、JUnit5常用注解 2.2.1、Test :表示方法是测试方法。…

【云原生 | 23】Docker运行Web服务实战之Tomcat

作者简介&#xff1a;&#x1f3c5;云计算领域优质创作者&#x1f3c5;新星计划第三季python赛道第一名&#x1f3c5; 阿里云ACE认证高级工程师&#x1f3c5; ✒️个人主页&#xff1a;小鹏linux &#x1f48a;个人社区&#xff1a;小鹏linux&#xff08;个人社区&#xff09;欢…

利用vue+高德地图API 实现用户的运动轨迹

利用vue高德地图API 实现用户的运动轨迹 高德地图网址&#xff1a;https://lbs.amap.com/api/jsapi-v2/guide/abc/prepare 任务一&#xff1a;实现地图显示 先完成准备工作&#xff0c;这一步是后面工作的基础。准备工作部分参考了&#xff1a; https://blog.csdn.net/qq_5…

vue3中vite的@路径别名与path中的resolve

使用路径引用 在vue3中&#xff0c;想用符号代替./…/这种相对路径引用使用&#xff0c; 前者相当于从根目录往后找&#xff0c;后者相当于从后往前找。 具体方法就是在vite.config.js中 import { resolve } from "path"export default defineConfig({plugins: [v…

Vue动态组件

等疫情结束了&#xff0c;要开始爬爬山、看看海&#xff0c;做些不会后悔的事情 一、概念 1. 示例 组件是可复用的 Vue 实例&#xff0c;且带有一个名字&#xff0c;这里实现一个最简单的组件&#xff1a; 父组件&#xff1a; <template><div><h1>Father…

【让CSDN的浪漫弥漫女神节】_Unity基础不动山不摇_回顾篇

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

promise 以及经典面试题

1.Promise 它是一个ES6提出一个新语法&#xff0c;用来优化异步代码的写法。promise&#xff1a;承诺 ● 生活中&#xff0c;它是用来表述 对将来要发生的事情的肯定。 例如 &#xff1a; 高中生说&#xff0c;老师&#xff0c;我会考上一所好大学的&#xff1b;销售员说&…

刷题日常计~JS④

作者 : SYFStrive 博客首页 : 点击跳转HomePage &#x1f4dc;&#xff1a; 初编程JavaScript之每天10&#x1f5e1;5题 &#x1f449; 从质变到量变&#x1f4aa; &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区…

Ajax 前后端数据交互

ajax 数据交互 今天又是奋斗的一天&#xff0c;行吧&#xff0c;来学习ajax ajax 数据交互什么是ajax&#xff1f;ajax的优势ajax的使用创建一个ajax对象配置这个对象发送请求接受返回过来的数据ajax状态码readystatechangeresponseTextajax请求方式封装一个属于自己的ajax什么…

2022年最新最详细在IDEA中配置Tomcat(含有详细图解过程)、建立使用IEDA建立一个Web项目的案例

1、首先已经成功安装过tomcat 如果没有成功安装&#xff0c;参考这篇tomcat安装教程(安装成功可忽略)&#xff1a;https://blog.csdn.net/weixin_43304253/article/details/117001797 2、在IDEA中配置tomcat的详细步骤 2.1、run ->Edit Confifurations 2.2 、点击加号 2.…

微信小程序自定义导航栏,实现不同用户角色登陆后显示不同的tabbar(避坑版)

在我们开发小程序的过程中&#xff0c;会遇到权限登录问题&#xff0c;不同的角色登录后显示的底部导航栏tabbar是不一样的。网上看到了很多的博客&#xff0c;多多少少会有些坑&#xff0c;会遇到问题。今天这篇博客就可以一次性解决。 了解概念 自定义tabbar 使用方法 app…

React修改Antd组件样式的方法

1.修改默认组件样式和写自己组件样式的区别 当我们写自己的样式时&#xff0c;在组件页面中定义class名称&#xff0c;再在less文件中对这个class定义样式。 //index.js import React,{useState} from react; import styles from ./index.less;const Index (props) >{ret…

36.一文讲透JavaScript日期对象Date,时间戳、1970、date方法、date计算

文章目录JavaScript日期和时间处理方法Date对象的创建new Date()new Date(milliseconds)1970年之前的时间&#xff1f;new Date(date_str)new Date(year, month, date, hours, minutes, sec, ms)Date对象的方法获取日期内容设置日期内容日期的自动校准日期转为数字、日期差值Da…

Node.js安装及环境配置之Windows篇

Node.js安装及环境配置之Windows篇Node.js安装及环境配置之Windows篇一、安装环境二、安装node.js步骤三、前期准备四、开始安装五、环境配置Node.js安装及环境配置之Windows篇 一、安装环境 1、本机系统&#xff1a;Windows 10&#xff08;64位&#xff09; 2、Node.js&…

纯js判断文件流格式类型:pdf,doc,docx,xls,xlsx,ppt,pptx一次搞定!

目录使用js判断文件类型的场景方法特点输入输出方法步骤1. 查看每种格式文件的16进制码&#xff0c;提取不同文件类型的“特征数”。2. 先判断大类型&#xff0c;在具体大类下判断小类型项目地址&#xff1a;纯前端基于react实现的多类型文件预览&#xff1a;通过arraybuffer判…

uniapp全局组件全局使用(不在每个页面template使用,仅支持H5),函数式调用全局组件方法

最简单的使用&#xff0c;在 main.js 编写如下代码&#xff0c;即可将 xxx 组件在每个页面显示 // main.js// 引入组件 import xxx from "/components/xxx.vue";// 将该组件挂载在document.body下 document.body.appendChild(new xxx().$mount().$el); 函数式调用全…

JS高级知识总结

文章目录1. this指向问题2. 对象进阶2.1 对象的定义和使用2.2 对象访问器2.2.1 Getter2.2.2 Setter2.3 对象构造器2.4 对象原型2.4.1 prototype属性2.4.2 \_\_proto\_\_ 属性2.4.3 constructor属性2.4.4 原型链2.5 Object对象2.5.1 管理对象2.5.2 保护对象3. 函数进阶3.1 函数的…

.Net Core中间件

目录 一、什么是中间件 二、中间件的用途 三、中间件的三个概念 四、自定义中间件 五、ASP.NET Core附带中间件组件 六、中间件和过滤器的区别 一、什么是中间件 在浏览网站或者使用手机App加载内容的时候&#xff0c;浏览器或者手机App其实在向Web服务器发送HTTP请求。服…

NodeJS安装(npm包管理器)

1、nodejs下载 windows下的NodeJS安装是比较方便的&#xff0c; 只需要登陆官网&#xff08;Node.js&#xff09;&#xff0c;直接点击64-bit下载安装 2、安装过程基本直接“NEXT”&#xff0c;NodeJS已经集成了npm&#xff0c;所以npm也一并安装好了 3、在cmd窗口输入node -…