用户登录案例——Servlet、JDBC、JavaBean的综合练习

这是一个非常简单的用户登录案例,用于对之前学过的知识练手

JavaBean:标准的Java类
1. 要求
* 1. 类必须被public修饰
* 2. 必须提供空参的构造方法
* 3. 成员变量必须使用private修饰
* 4. 提供公共setter和getter方法
2. 功能:封装数据

BeanUtils工具类:用于快速封装JavaBean

方法:
1. setProperty(JavaBean对象,属性名,属性值):用于给JavaBean对象中的属性赋值。
2. getProperty(JavaBean对象,属性名):根据属性名获取JavaBean对象中的值。
3. populate(Object obj , Map map):将map集合的键值对信息,直接封装到对应的JavaBean对象中。不再需要我们手动调用setter方法。

一、用户登录案例需求
1.编写login.html登录页面
* 有用户名和密码两个输入框,一个登录按钮。
2.使用Servlet获取输入的用户名和密码,使用BeanUtils封装User对象。
3.使用Druid数据库连接池技术,查询mysql中qiniuyun数据库的user表。
4.使用JdbcTemplate技术完成SQL语句的执行操作。
5.登录成功跳转到loginSucceed,显示:登录成功![用户名],欢迎您。
6.登录失败跳转到loginFailed,显示:登录失败,用户名或密码错误。

二、案例分析

三、实现步骤

1.编写HTML表单页面放在web文件夹根目录,只需要有用户名和密码两个输入框,一个登录按钮即可。其中action的书写格式:虚拟目录+ Servlet资源路径

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form action="/loginDemo/loginServlet" method="post">
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>
</body>
</html>

2.在mysql中创建数据库和user表,并自己添加一些记录。

CREATE DATABASE qiniuyun;
USE qiniuyun;
CREATE TABLE user(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(32) UNIQUE NOT NULL,
    PASSWORD VARCHAR(32) NOT NULL
);

3.创建User类,放在domain包下,这个类是JavaBean

User.java

package LoginDemo.domain;

public class User {
    private int id;
    private String username;
    private String password;
    private String gender;

    public void setGender(String gender){
        this.gender = gender;
    }
    public String getGender(){
        return gender;
    }
    public int getId() {
        return id;
    }
    public void setId(int 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 + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

4.编写Druid连接池配置文件druid.properties,放在util包下,并将MySQL的JDBC驱动JAR包导入到项目中。

druid.properties

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://anonyeast.top:3306/qiniuyun?serverTimezone=Asia/Shanghai&useSSL=false
username=qiniuyun
password=123456
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间(毫秒)
maxWait=3000
# 验证连接是否可用使用的SQL语句
validationQuery=SELECT 1
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除
testWhileIdle=true

5.编写JDBC工具类JDBCUtils,放在util包下,并将Druid连接池的JAR包导入到项目中。

JDBCUtils.java

package LoginDemo.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtils {
    private static DataSource ds = null;

    static {
        try {
            Properties prop = new Properties();
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("LoginDemo/util/druid.properties");
            prop.load(is);
            ds = DruidDataSourceFactory.createDataSource(prop);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 获取连接池对象
     */
    public static DataSource getDataSource(){
        return ds;
    }
    
    /**
     * 获取连接对象
     */
    public static Connection getConnection(){
        try {
            return ds.getConnection();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }
    }
}

6.创建类UserDao,放在dao包下。该类提供login方法,用于查询输入的用户名和密码在数据库中是否存在。使用了Spring中的JdbcTemplate技术,将Spring相关依赖JAR包导入到项目中。

UserDao.java

package LoginDemo.dao;

import LoginDemo.domain.User;
import LoginDemo.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

public class UserDao {
    //声明JDBCTemplate对象共用
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());

    /**
     * 登录方法
     * @param loginUser:只有用户名和密码
     * @return User对象:包含用户全部数据。如果没有查询到,返回null。
     */
    public User login(User loginUser){
        try {
            //1.编写SQL
            String sql = "select * from user where username = ? and password = ?";
            //2.调用query方法
            User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),
                    loginUser.getUsername(), loginUser.getPassword());
            //3.返回User对象
            return user;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}

7.测试UserDao中的login方法能否正常使用,写一个测试类UserDaoTest,放在test包中,并将Junit单元测试的依赖JAR包导入到项目中。执行测试,输出结果正常,说明UserDao可以正常使用。

UserDaoTest.java

package LoginDemo.test;

import LoginDemo.dao.UserDao;
import LoginDemo.domain.User;
import org.junit.Test;

public class UserDaoTest {
    @Test
    public void testLogin(){
        User loginUser = new User();
        UserDao dao = new UserDao();

        loginUser.setUsername("指尖代码");
        loginUser.setPassword("123456");

        User user = dao.login(loginUser);
        System.out.println(user);
    }
}
输出结果:User{id=3, username='指尖代码', password='123456', gender='null'}

8.编写LoginServlet类,用于获取用户名和密码。使用了BeanUtils工具类将login.html提交的用户名和密码快速封装为User对象,因此需要导入BeanUtils工具类的依赖JAR包到项目中。

package LoginDemo.servlet;

import LoginDemo.dao.UserDao;
import LoginDemo.domain.User;
import org.apache.commons.beanutils.BeanUtils;

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.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //1.设置编码
            request.setCharacterEncoding("utf-8");
            //传统方式封装对象
//        //2.获取请求参数
//        String username = request.getParameter("username");
//        String password = request.getParameter("password");
//        //3.封装User对象
//        User loginUser = new User();
//        loginUser.setUsername(username);
//        loginUser.setPassword(password);
            //现代方式:使用BeanUtils快速封装对象
            //2.获取所有参数
            Map<String, String[]> map = request.getParameterMap();
            //3.使用BeanUtils快速封装User对象
            User loginUser = new User();
            BeanUtils.populate(loginUser,map);
            //4.调用UserDao的login方法获取User对象
            User user = new UserDao().login(loginUser);
            //5.判断user是否获取到
            if (user == null) {
                //登录失败,跳转到登陆失败页
                request.getRequestDispatcher("/loginFailed").forward(request,response);
            }else{
                //登录成功
                //存储数据
                request.setAttribute("user",user);
                //转发
                request.getRequestDispatcher("/loginSucceed").forward(request,response);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

9.编写LoginFailed类,显示:登陆失败,用户名或密码错误。

LoginFailed.java

package LoginDemo.servlet;

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;

@WebServlet("/loginFailed")
public class LoginFailed extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码
        response.setContentType("text/html;charset=utf-8");
        //输出
        response.getWriter().write("登陆失败,用户名或密码错误");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

10.编写LoginSucceed类,显示:登陆成功![输入的用户名],欢迎您。

LoginSucceed.java

package LoginDemo.servlet;

import LoginDemo.domain.User;

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;

@WebServlet("/loginSucceed")
public class LoginSucceed extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //给页面写一句话
        //设置编码
        response.setContentType("text/html;charset=utf-8");
        //获取request域中共享的user对象
        User user = (User) request.getAttribute("user");
        if (user != null) {
            //输出
            response.getWriter().write("登陆成功!" + user.getUsername() + ",欢迎您");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

11.将所有使用到的JAR包放入WEB-INF/lib目录下。

四、演示

1.项目结构

其中lib目录下为这个项目使用到的jar包。

2.演示效果

数据库中已有的帐号和密码如下

输入用户名:指尖代码 密码:123456,点击登录

登录成功

随意输入用户名和密码

登陆失败

AnonyEast

一个爱折腾的技术萌新

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐