一、登陆页: login.jsp
<%@ page contentType="text/html; charset=UTF-8" import="java.util.*" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>用户登录</title>
<script type="text/javascript">
function validate(f)
{
if(!(/^\w{5,15}$/.test(f.userid.value)))
{
alert("用户 ID 长度必须在 5 ~ 15 位之间!");
f.userid.focus(); // 把焦点放到用户 ID 框中
false;
}
if(!(/^\w{5,15}$/.test(f.userpass.value)))
{
alert("密码长度必须在 5 ~ 15 为之间!");
f.userpass.focus(); // 把焦点放到密码框中
return false;
}
return true;
}
</script>
</head>
<body>
<h2>用户登陆</h2>
<%
request.setCharacterEncoding("UTF-8"); // 设置接收参数编码格式为 UTF-8
%>
<%
List<String> info = (List<String>)request.getAttribute("info"); // 提取错误提示信息
if(info != null) // 存在错误提示信息,登陆失败!
{
Iterator<String> iter = info.iterator(); // 实例化 Iterator 类
while(iter.hasNext())
{
%>
<h3><%= iter.next() %></h3>
<%
}
}
%>
<form action="Login" method="post" onSubmit="return validate(this)">
用户ID:<input type="text" name="userid" /><br />
密 码:<input type="password" name="userpass" size="22px" /><br />
<input type="submit" value=" 登 陆 " />
<input type="reset" value=" 重 置 " />
</form>
</body>
</html>
二、数据库脚本:
-- 判断数据库是否已存在,如果存在则删除
DROP DATABASE IF EXISTS etecha;
-- 创建数据库 etecha
create database etecha;
-- 进入数据库 etecha 中
use etecha;
-- 判断用户表 user 是否已存在,如果存在则删除
DROP TABLE IF EXISTS user;
create table user
(
userid varchar(30) primary key, -- 主键,用户ID
name varchar(30) not null, -- 用户名
password varchar(32) not null -- 密码
)ENGINE=MyISAM DEFAULT CHARSET=utf8;
insert into user(userid, name, password) values('admin', 'administrator', '123');
三、VO 类: User.java
package com.etecha.api.vo;
public class User
{
private String userid;
private String name;
private String password;
public String getUserid()
{
return this.userid;
}
public void setUserid(String userid)
{
this.userid = userid;
}
public String getName()
{
return this.name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return this.password;
}
public void setPassword(String password)
{
this.password = password;
}
}
四、DAO 类:IUserDAO.java
package com.etecha.api.dao;
import com.etecha.api.vo.User;
public interface IUserDAO
{
public boolean findLogin(User user) throws Exception;
}
五、数据库连接类:DatabaseConnection.java
package com.etecha.api.dbc;
import java.sql.Connection;
import java.sql.DriverManager;
public class DatabaseConnection
{
private static final String DBDRIVER = "com.mysql.jdbc.Driver";
private static final String DBURL = "jdbc:mysql://localhost:3306/etecha";
private static final String DBUSER = "root";
private static final String DBPASSWORD = "123";
private Connection conn = null;
// 在构造方法中进行数据库的连接
public DatabaseConnection() throws Exception
{
try
{
Class.forName(DBDRIVER); // 运用反射机制加载数据库驱动程序
this.conn = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD); // 建立与数据库的连接
}
catch (Exception e)
{
throw e;
}
}
public Connection getConnection()
{
return this.conn; // 取得当前连接
}
public void close() throws Exception
{
if(this.conn != null)
{
try
{
this.conn.close(); // 如果已建立连接则断开当前连接
}
catch (Exception e)
{
throw e;
}
}
}
}
六、DAO工厂类:DAOFactory.java
package com.etecha.api.factory;
import com.etecha.api.dao.IUserDAO;
import com.etecha.api.dao.proxy.UserDAOProxy;
// 取得 DAO 实例
public class DAOFactory
{
public static IUserDAO getIUserDAOInstance()
{
return new UserDAOProxy(); // 返回代理实例
}
}
七、DAO 实现类: UserDAOImpl.java
package com.etecha.api.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.etecha.api.dao.IUserDAO;
import com.etecha.api.vo.User;
// DAO 实现类
public class UserDAOImpl implements IUserDAO
{
private Connection conn = null; // 声明数据库连接对象
private PreparedStatement pstmt = null; // 声明数据库操作对象
// 在构造方法中设置数据库的连接
public UserDAOImpl(Connection conn)
{
this.conn = conn;
}
public boolean findLogin(User user) throws Exception
{
boolean flag = false;
try
{
String sql = "SELECT name FROM user WHERE userid = ? AND password = ?"; // 构造 SQL 语句
this.pstmt = this.conn.prepareStatement(sql); // 加载 SQL 语句,实例化操作
this.pstmt.setString(1, user.getUserid()); // 设置 ID
this.pstmt.setString(2, user.getPassword()); // 设置 Password
ResultSet rs = this.pstmt.executeQuery(); // 取得查询结果
if(rs.next())
{
user.setName(rs.getString(1));
flag = true;
}
}
catch (Exception e)
{
throw e; // 向上抛出异常
}
finally
{
if(this.pstmt != null)
{
try
{
this.pstmt.close(); // 如果与数据库的操作处于连接状态则关闭
}
catch (Exception e)
{
throw e;
}
}
}
return flag;
}
}
八、DAO 代理类:UserDAOProxy.java
package com.etecha.api.dao.proxy;
import com.etecha.api.dao.IUserDAO;
import com.etecha.api.dao.impl.UserDAOImpl;
import com.etecha.api.dbc.DatabaseConnection;
import com.etecha.api.vo.User;
// DAO 代理类
public class UserDAOProxy implements IUserDAO
{
private DatabaseConnection dbc = null; // 声明数据库连接对象
private IUserDAO dao = null; // 声明 DAO 接口
// 在构造方法中实例化与数据库的连接
public UserDAOProxy()
{
try
{
this.dbc = new DatabaseConnection(); // 实例化数据库连接
}
catch (Exception e)
{
e.printStackTrace();
}
this.dao = new UserDAOImpl(this.dbc.getConnection()); // 把连接结果返回到 DAO 接口
}
public boolean findLogin(User user) throws Exception
{
boolean flag = false;
try
{
flag = this.dao.findLogin(user); // 通过 DAO 接口判断用户名是否合法
}
catch (Exception e)
{
throw e;
}
finally
{
this.dbc.close(); // 关闭与数据库的连接
}
return flag;
}
}
九、Servlet:LoginServlet.java
package com.etecha.api.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.etecha.api.factory.DAOFactory;
import com.etecha.api.vo.User;
public class LoginServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String path = "login.jsp";
String userid = request.getParameter("userid"); // 接收 userid 内容
String userpass = request.getParameter("userpass"); // 接收 userpass 内容
List<String> info = new ArrayList<String>();
if(userid == null || "".equals(userid))
{
info.add("<span style='color:red'>用户 id 不能为空!</span>"); // 错误提示信息
}
if(userpass == null || "".equals(userpass))
{
info.add("<span style='color:red'>密码不能为空!</span>"); // 密码错误提示
}
if(info.size() == 0) // 用户通过验证
{
User user = new User(); // 实例化 VO 类
user.setUserid(userid); // 把 userid 添加到 VO 对象 user 中
user.setPassword(userpass); // 把 userpass 添加到 VO 对象 user 中
try
{
if(DAOFactory.getIUserDAOInstance().findLogin(user)) // 验证通过
{
info.add("登陆成功!欢迎<font size=14 color=red> " + user.getName() + " </font>光临本站!");
}
else // 登陆失败
{
info.add("<span style='color:red'>登陆失败!用户名或密码错误!</span>");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
request.setAttribute("info", info); // 保存错误信息
request.getRequestDispatcher(path).forward(request, response); // 跳转到登陆页面
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
this.doGet(request, response);
}
}
十、web.xml 配置文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet> <!-- 定义 Servlet -->
<servlet-name>login</servlet-name> <!-- 与 servlet-mapping 相对应,名字必须完全相同 -->
<servlet-class>com.etecha.api.servlet.LoginServlet</servlet-class> <!-- 定义具体的包.类名 -->
</servlet>
<servlet-mapping> <!-- 映射路径 -->
<servlet-name>login</servlet-name> <!-- 与 servlet 相对应,名字和 servlet 完全相同 -->
<url-pattern>/Login</url-pattern> <!-- 页面的映射路径。虚拟路径 -->
</servlet-mapping>
</web-app>