目录导航

用户登录注销是Web应用最常见的功能。在创建登录表单的示例中,我们使用了DAO(数据访问对象),Factory()方法和DTO(数据传输对象)设计模式。

注:本示例是基于上一节:JSP用户注册功能实践之上加以实现。

打开Eclipse,创建一个动态Web项目:jsp-userlogin,项目结构如下:

此项目主要有以下文件:

  • index.jsp - 它提供了三个用于登录,注销和配置文件的链接。
  • login.jsp - 一个表单页面,用于从用户获取值。
  • logincheck.jsp - 一个处理请求并调用方法的jsp文件。
  • User.java - 一个具有属性以及settergetter方法的bean类。
  • DBProvider.java - 一个包含许多常量的接口,例如:DRIVER_CLASSCONNECTION_URLUSERNAMEPASSWORD
  • DBConnection.java - 一个负责返回Connection对象的类。它使用单例和工厂方法设计模式。
  • UserDao.java - 一个DAO类,用于验证数据库中的emailpassword
  • logout.jsp - 它使会话无效。
  • profile.jsp - 如果用户已登录,它将提供简单消息,否则将请求转发到login.jsp页面。

在此示例中,我们使用MySQL数据库将email和密码与数据库表中的记录进行匹配。表名称为:xn_user,其中包含许多字段,如名称,电子邮件,密码等。可以使用以下SQL语句来创建表:

CREATE TABLE `xn_user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT '',
  `password` varchar(32) DEFAULT '',
  `email` varchar(255) DEFAULT '',
  `instro` varchar(255) DEFAULT '',
  `status` tinyint(1) unsigned DEFAULT '0',
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=124 DEFAULT CHARSET=utf8;

文件:index.jsp

这是一个简单登录页面,只是提供了登录,注销和个人资料的链接。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP用户登录注销实践(xntutor.com)</title>
<link rel="stylesheet"
    href="http://www.xntutor.com/static/css/fordemo.css?v=v.1.0894">
</head>
<body class="inside-header inside-aside is-dialog">
    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <div class="row">
            <a href="login.jsp">登录</a>| <a href="logout.jsp">注销</a>| <a
                href="profile.jsp">个人资料</a>
        </div>
    </div>
</body>
</html>

文件:login.jsp

此文件创建一个登录表单,显示两个输入字段:用户名和密码。 这是简单的登录表单,你可以增加样式让它变得漂亮一些。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP用户登录注销实践(xntutor.com)</title>
</head>
<link rel="stylesheet"
    href="http://www.xntutor.com/static/css/fordemo.css?v=v.1.0894">
<body class="is-dialog">

    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <div class="row">
            <%@ include file="index.jsp"%>
            <hr />

            <%
                String profile_msg = (String) request.getAttribute("profile_msg");
                if (profile_msg != null) {
                    out.print(profile_msg);
                }
                String login_msg = (String) request.getAttribute("login_msg");
                if (login_msg != null) {
                    out.print(login_msg);
                }
            %>
            <br />
            <form class="form-horizontal" action="logincheck.jsp" method="post">
                <h2 style="width: 100%; text-align: center; padding: 48px;">JSP用户登录功能实践</h2>

                <div class="form-group">
                    <label for="name" class="control-label col-xs-12 col-sm-4">用户名(Email):</label>
                    <div class="col-xs-12 col-sm-4">
                        <input id="name" class="form-control" name="email" type="text"
                            value="">
                    </div>
                </div>

                <div class="form-group">
                    <label for="name" class="control-label col-xs-12 col-sm-4">密码:</label>
                    <div class="col-xs-12 col-sm-4">
                        <input id="name" class="form-control" name="passwd"
                            type="password" value="">
                    </div>
                </div>

                <div class="form-group">
                    <label class="control-label col-xs-12 col-sm-4"></label>
                    <div class="col-xs-12 col-sm-4">
                        <button type="submit" class="btn btn-success btn-embossed">登录</button>

                    </div>
                </div>
            </form>
        </div>
    </div>
</body>
</html>

文件:logincheck.jsp

这个jsp文件包含所有到bean类的对象的传入值,该类作为参数传递给LoginDao类的validate方法。 如果email和密码正确,则会显示一条消息,提示:您已成功登录! 并保持会话状态,以便识别当前登录的用户信息。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录处理(xntutor.com)</title>
</head>
<body>
    <%@page import="com.xntutor.dao.UserDao"%>
    <jsp:useBean id="obj" class="com.xntutor.bean.User" />
    <jsp:setProperty property="*" name="obj" />
    <%
        boolean status = UserDao.checkLogin(obj);
        if (status) {
            out.println("You are successfully logged in");
            session.setAttribute("isLogin", "TRUE");
            session.setAttribute("username", obj.getEmail());
            response.sendRedirect("profile.jsp");
        } else {
            out.print("Sorry, email or password error");
    %>
    <jsp:include page="index.jsp"></jsp:include>
    <%
        }
    %>
</body>
</html>

文件:User.java

此User类具有几个个属性,并通过其settergetter方法传递电子邮件(email)。

package com.xntutor.bean;

public class User {
    private int id;
    private String name;
    private String passwd;
    private String email;
    private String instro;
    private int status;
    private String created;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String password) {
        this.passwd = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getInstro() {
        return instro;
    }

    public void setInstro(String instro) {
        this.instro = instro;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getCreated() {
        return created;
    }

    public void setCreated(String created) {
        this.created = created;
    }

}

文件:DBProvider.java

此接口包含四个常量,每个数据库的常量可能不同。

package com.xntutor.db;

public class DBProvider {
    static String DRIVER = "com.mysql.cj.jdbc.Driver";
    static String CONNECTION_URL = "jdbc:mysql://localhost/testdb?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8";
    static String DBNAME = "testdb";
    static String USERNAME = "root";
    static String PASSWORD = "123456";
}

文件:DBConnection.java

此类提供了一个工厂方法,该方法返回Connection的对象。 在此,驱动程序类仅加载一次,并且连接对象仅静态获取一次内存。

package com.xntutor.db;

import java.sql.*;


public class DBConnection {
    private static Connection con = null;
    static {
        try {
            Class.forName(DBProvider.DRIVER);
            con = DriverManager.getConnection(DBProvider.CONNECTION_URL, DBProvider.USERNAME, DBProvider.PASSWORD);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        System.out.println("Connect to MySQL...");
        return con;
    }

}

文件:UserDao.java

此类用于更改email和密码。

package com.xntutor.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.xntutor.bean.User;
import com.xntutor.db.DBConnection;

public class UserDao {

    public static boolean checkLogin(User user) {

        boolean status = false;
        try {
            Connection con = DBConnection.getConnection();

            PreparedStatement ps = con.prepareStatement("select * from xn_user where email=? and password=?");
            System.out.println("email=>"+user.getEmail());
            System.out.println("Passwd=>"+user.getPasswd());
            ps.setString(1, user.getEmail());
            ps.setString(2, user.getPasswd());

            ResultSet rs = ps.executeQuery();
            status = rs.next();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return status;
    }
}

运行上面项目,访问URL: