JavaWeb:用户注册登录案例 冷不防 2024-03-30 13:39 21阅读 0赞 ### 1.1 用户登录 ### #### 1.1.1 需求分析 #### ![在这里插入图片描述][111eeb6d28c340078dfa90c9b6a53956.png_pic_center] 1. 用户在登录页面输入用户名和密码,提交请求给`LoginServlet` 2. 在`LoginServlet`中接收请求和数据\[用户名和密码\] 3. 在`LoginServlt`中通过`Mybatis`实现调用`UserMapper`来根据用户名和密码查询数据库表 4. 将查询的结果封装到`User`对象中进行返回 5. 在`LoginServlet`中判断返回的`User`对象是否为`null` 6. 如果为`nul`,说明根据用户名和密码没有查询到用户,则登录失败,返回"登录失败"数据给前端 7. 如果不为`null`,则说明用户存在并且密码正确,则登录成功,返回"登录成功"数据给前端 #### 1.1.2 环境准备 #### 1. 复制静态页面到项目的`webapp`目录下,效果如下: ![在这里插入图片描述][783f00544bcc458eaac445d004d8e9b3.png_pic_center] 1. 创建db1数据库,创建tb\_user表,创建User实体类 2.1 将sql语句执行下: ![在这里插入图片描述][b3e6fca6225b4e938f6a14c889b0af67.png_pic_center] 2.2 创建`User.java`实体类 package com.dcxuexi.pojo; /*** * @Title User * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 16:33 * @Version 1.0.0 */ public class User { private Integer id; private String username; private String password; public Integer getId() { return id; } 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 + '\'' + '}'; } } 1. 在项目的`pom.xml`导入`Mybatis`和`Mysql`驱动坐标 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.10</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> 1. 创建`mybatis-config.xml`核心配置文件,`UserMapper.xml`映射文件,`UserMapper`接口 4.1 在`resources`目录下创建`mybatis-config.xml`配置文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--起别名--> <typeAliases> <package name="com.dcxuexi.pojo"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <!-- useSSL:关闭SSL安全连接 性能更高 useServerPrepStmts:开启预编译功能 & 等同于 & ,xml配置文件中不能直接写 &符号 --> <property name="url" value="jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true"/> <property name="username" value="root"/> <property name="password" value="1234"/> </dataSource> </environment> </environments> <mappers> <!--扫描mapper--> <package name="com.dcxuexi.mapper"/> </mappers> </configuration> 4.2 在`com.dcxuexi.mapper`包下创建`UserMapper`接口 package com.dcxuexi.mapper; /*** * @Title UserMapper * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 16:45 * @Version 1.0.0 */ public interface UserMapper { } 4.3 `resources`目录下创建`UserMapper.xml` 注意:在`resources`下创建`UserMapper.xml`的目录时,要使用`/`分割 ![在这里插入图片描述][d08f3d21a9fb48808f5887c3ce1ff672.png_pic_center] <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.dcxuexi.mapper.UserMapper"> </mapper> 至此我们所需要的环境就都已经准备好了,具体该如何实现? #### 1.1.3 代码实现 #### 1. 在`UserMapper`接口中提供一个根据用户名和密码查询用户对象的方法 package com.dcxuexi.mapper; import com.dcxuexi.pojo.User; import org.apache.ibatis.annotations.Param; /*** * @Title UserMapper * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 16:45 * @Version 1.0.0 */ public interface UserMapper { /** * 根据用户名和密码查询用户对象 * @param username * @param password * @return */ User select(@Param("username") String username, @Param("password") String password); } `UserMapper.xml`实现根据用户名和密码查询用户对象。 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.dcxuexi.mapper.UserMapper"> <select id="select" resultType="com.dcxuexi.pojo.User"> select * from tb_user where username = #{username} and password = #{password} </select> </mapper> **说明** `@Param`注解的作用:用于传递参数,是方法的参数可以与`SQL`中的字段名相对应。 1. 修改`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="/request_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"> <a href="register.html">没有账号?点击注册</a> </div> </form> </div> </body> </html> 1. 编写`LoginServlet` @WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. 接收用户名和密码 String username = request.getParameter("username"); String password = request.getParameter("password"); //2. 调用MyBatis完成查询 //2.1 获取SqlSessionFactory对象 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2.2 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //2.3 获取Mapper UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //2.4 调用方法 User user = userMapper.select(username, password); //2.5 释放资源 sqlSession.close(); //获取字符输出流,并设置content type response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); //3. 判断user释放为null if(user != null){ // 登陆成功 writer.write("登陆成功"); }else { // 登陆失败 writer.write("登陆失败"); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } } 1. 启动服务器测试![在这里插入图片描述][90c0dbd4639842529fc35f10b29163f4.png_pic_center] 4.1 如果用户名和密码输入错误,则 ![在这里插入图片描述][7aafb6e760e54525bc50954e8308c6e4.png_pic_center] 4.2 如果用户名和密码输入正确,则 ![在这里插入图片描述][22c9c0f3e4f04f53bb45bc555cee1156.png_pic_center] 至此用户的登录功能就已经完成了。 ### 1.2 用户注册 ### #### 1.2.1 需求分析 #### ![在这里插入图片描述][1a2ba4b46f16405a81bf63280ced8b97.png_pic_center] 1. 用户在注册页面输入用户名和密码,提交请求给`RegisterServlet` 2. 在`RegisterServlet`中接收请求和数据\[用户名和密码\] 3. 在`RegisterServlet`中通过`Mybatis`实现调用`UserMapper`来根据用户名查询数据库表 4. 将查询的结果封装到`User`对象中进行返回 5. 在`RegisterServlet`中判断返回的`User`对象是否为`null` 6. 如果为`nul`,说明根据用户名可用,则调用`UserMapper`来实现添加用户 7. 如果不为`null`,则说明用户不可以,返回"用户名已存在"数据给前端 #### 1.2.2 代码编写 #### 1. 编写UserMapper提供根据用户名查询用户数据方法和添加用户方法 package com.dcxuexi.mapper; import com.dcxuexi.pojo.User; import org.apache.ibatis.annotations.Param; /*** * @Title UserMapper * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 16:45 * @Version 1.0.0 */ public interface UserMapper { /** * 根据用户名和密码查询用户对象 * @param username * @param password * @return */ User select(@Param("username") String username, @Param("password") String password); /** * 根据用户名查询用户对象 * @param username * @return */ User selectByUsername(String username); /** * 添加用户 * @param user */ void add(User user); } `UserMapper.xml`实现方法 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.dcxuexi.mapper.UserMapper"> <select id="select" resultType="com.dcxuexi.pojo.User"> select * from tb_user where username = #{username} and password = #{password} </select> <select id="selectByUsername" resultType="com.dcxuexi.pojo.User"> select * from tb_user where username = #{username} </select> <insert id="add"> insert into tb_user values(null,#{username},#{password}) </insert> </mapper> 1. 修改`register.html` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>欢迎注册</title> <link href="css/register.css" rel="stylesheet"> </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="/request_demo/registerServlet" method="post"> <table> <tr> <td>用户名</td> <td class="inputs"> <input name="username" type="text" id="username"> <br> <span id="username_err" class="err_msg" style="display: none">用户名不太受欢迎</span> </td> </tr> <tr> <td>密码</td> <td class="inputs"> <input name="password" type="password" id="password"> <br> <span id="password_err" class="err_msg" style="display: none">密码格式有误</span> </td> </tr> </table> <div class="buttons"> <input value="注 册" type="submit" id="reg_btn"> </div> <br class="clear"> </form> </div> </body> </html> 1. 创建`RegisterServlet`类 package com.dcxuexi.web; import com.dcxuexi.mapper.UserMapper; import com.dcxuexi.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; /*** * @Title RegisterServlet * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 17:47 * @Version 1.0.0 */ @WebServlet("/registerServlet") public class RegisterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 接收用户数据 String username = req.getParameter("username"); String password = req.getParameter("password"); //封装用户对象 User user = new User(); user.setUsername(username); user.setPassword(password); //2. 调用mapper 根据用户名查询用户对象 //2.1 获取SqlSessionFactory对象 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2.2 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //2.3 获取Mapper UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //2.4 调用方法 User user2 = userMapper.selectByUsername(username); resp.setContentType("text/html;charset=utf-8"); //3. 判断用户对象释放为null if (user2 == null){ // 用户名不存在,添加用户 userMapper.add(user); // 提交事务 sqlSession.commit(); // 释放资源 sqlSession.close(); resp.getWriter().write("用户注册成功"); }else { // 用户名存在,给出提示信息 resp.getWriter().write("用户名已存在"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } } 1. 启动服务器进行测试![在这里插入图片描述][cb27260781ed4ace9ac84d67433a5b3a.png_pic_center] 4.1 如果测试成功,则在数据库中就能查看到新注册的数据![在这里插入图片描述][62e43d9f9c604d329268d25b5f083d01.png_pic_center] 4.2 如果用户已经存在,则在页面上展示 `用户名已存在` 的提示信息![在这里插入图片描述][a3f464a23cee4721b25140b7ca46de5b.png_pic_center] ### 1.3 `SqlSessionFactory`工具类抽取 ### 上面两个功能已经实现,但是在写`Servlet`的时候,因为需要使用`Mybatis`来完成数据库的操作,所以对于`Mybatis`的基础操作就出现了些重复代码,如下 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 有了这些重复代码就会造成一些问题: * 重复代码不利于后期的维护 * `SqlSessionFactory`工厂类进行重复创建 * 就相当于每次买手机都需要重新创建一个手机生产工厂来给你制造一个手机一样,资源消耗非常大但性能却非常低。所以这么做是不允许的。 那如何来优化呢? * 代码重复可以抽取工具类 * 对指定代码只需要执行一次可以使用静态代码块 有了这两个方向后,代码具体该如何编写? package com.dcxuexi.util; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; /*** * @Title SqlSessionFactoryUtils * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 18:05 * @Version 1.0.0 */ public class SqlSessionFactoryUtils { private static SqlSessionFactory sqlSessionFactory; static { //静态代码块会随着类的加载而自动执行,且只执行一次 try { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSessionFactory getSqlSessionFactory(){ return sqlSessionFactory; } } 工具类抽取以后,以后在对`Mybatis`的`SqlSession`进行操作的时候,就可以直接使用 SqlSessionFactory sqlSessionFactory =SqlSessionFactoryUtils.getSqlSessionFactory(); 这样就可以很好的解决上面所说的代码重复和重复创建工厂导致性能低的问题了。 `LoginServlet`类优化如下: package com.dcxuexi.web; import com.dcxuexi.mapper.UserMapper; import com.dcxuexi.pojo.User; import com.dcxuexi.util.SqlSessionFactoryUtils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; /*** * @Title LoginServlet * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 17:02 * @Version 1.0.0 */ @WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 接收用户名和密码 String username = req.getParameter("username"); String password = req.getParameter("password"); System.out.println("username = " + username); //2. 调用MyBatis完成查询 //2.1 获取SqlSessionFactory对象 //String resource = "mybatis-config.xml"; //InputStream inputStream = Resources.getResourceAsStream(resource); //SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory(); //2.2 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //2.3 获取Mapper UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //2.4 调用方法 User user = userMapper.select(username, password); //2.5 释放资源 sqlSession.close(); //获取字符输出流,并设置content type resp.setContentType("text/html;charset=utf-8"); PrintWriter writer = resp.getWriter(); if (user!=null){ // 登陆成功 writer.write(username+"登陆成功"); }else { // 登陆失败 writer.write("登陆失败"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } } `RegisterServlet`类优化如下: package com.dcxuexi.web; import com.dcxuexi.mapper.UserMapper; import com.dcxuexi.pojo.User; import com.dcxuexi.util.SqlSessionFactoryUtils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; /*** * @Title RegisterServlet * @Description TOTD * @Auter DongChuang * @Date 2023/1/1 17:47 * @Version 1.0.0 */ @WebServlet("/registerServlet") public class RegisterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 接收用户数据 String username = req.getParameter("username"); String password = req.getParameter("password"); //封装用户对象 User user = new User(); user.setUsername(username); user.setPassword(password); //2. 调用mapper 根据用户名查询用户对象 //2.1 获取SqlSessionFactory对象 //String resource = "mybatis-config.xml"; //InputStream inputStream = Resources.getResourceAsStream(resource); //SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory(); //2.2 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //2.3 获取Mapper UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //2.4 调用方法 User user2 = userMapper.selectByUsername(username); resp.setContentType("text/html;charset=utf-8"); //3. 判断用户对象释放为null if (user2 == null){ // 用户名不存在,添加用户 userMapper.add(user); // 提交事务 sqlSession.commit(); // 释放资源 sqlSession.close(); resp.getWriter().write("用户注册成功"); }else { // 用户名存在,给出提示信息 resp.getWriter().write("用户名已存在"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } } [111eeb6d28c340078dfa90c9b6a53956.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/4e67fba8169b4db6815e9584d454494e.png [783f00544bcc458eaac445d004d8e9b3.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/0aae0caa5d2b4d4abac030802c9c56b7.png [b3e6fca6225b4e938f6a14c889b0af67.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/67b07156528a4379941c7b183d42dfb6.png [d08f3d21a9fb48808f5887c3ce1ff672.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/c5d5d3badf4040a3860fb5955fc9437b.png [90c0dbd4639842529fc35f10b29163f4.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/b31c9d4814b44ec9a2a9fce2c2419e2b.png [7aafb6e760e54525bc50954e8308c6e4.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/01bc2242a3394051bf0305569c093861.png [22c9c0f3e4f04f53bb45bc555cee1156.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/3391d4227aa94b08a30a2226ad1c77eb.png [1a2ba4b46f16405a81bf63280ced8b97.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/f7fb191da90f45948c35ca8a6cddd130.png [cb27260781ed4ace9ac84d67433a5b3a.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/4d0debf46ede48f78a7b67404c842e7b.png [62e43d9f9c604d329268d25b5f083d01.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/0a679e9c556542cfb2d19cc48a6733b3.png [a3f464a23cee4721b25140b7ca46de5b.png_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/fcd24d4656ac4dcdadd27f20abe4d44d.png
还没有评论,来说两句吧...