文章目录
提示:以下是本篇文章正文内容,Java系列学习将会持续更新
程序的流程
- 静态页面:
login.html
—(POST请求
)—>/login.do
- 静态页面:
register.html
—(POST请求
)—>/register.do
- 动态页面:
URL+回车
—(GET请求
)—>/publish.html
- 注册 —> 登录 —> 个人动态页面
- 用户只有登录后,才能访问到动态页面。
正是Cookie + Session会话机制的应用:
- 用户成功登录后,服务器会生成一个session对象,来存储用户的登录状态。
- 服务器依赖cookie将 session-id传递给客户端(浏览器),客户端保存 cookie 值。
- 客户端(浏览器)每次请求的时候,都会携带 cookie 值。
如果能对上,说明用户已经登录,则可以访问到个人动态页面。
如果对不上,说明用户还没有登录,则访问不到,需要重新登录。
main
java
dao
UserDao
// SQL 操作
public class UserDao { // 单例模式, 饿汉式
private static UserDao userDao = new UserDao();
private UserDao() { }
public static UserDao getUserDao() {
return userDao;
}
public User selectOneByUsernameAndPassword(String username, String password) {
try (Connection c = DBUtil.connection()) {
String sql = "select uid from users where username = ? and password = ?";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, username);
ps.setString(2, password);
System.out.println("执行 SQL: " + ps);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) {
return null;
}
return new User(rs.getInt("uid"), username, password);
}
}
} catch (SQLException exc) {
throw new RuntimeException(exc);
}
}
public User insert(String username, String password) {
// TODO: 表中的username不能重复,暂时不考虑如何解决重复的问题
try (Connection c = DBUtil.connection()) {
String sql = "insert into users (username, password) values (?, ?)";
try (PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
ps.setString(1, username);
ps.setString(2, password);
ps.executeUpdate();
int uid;
try (ResultSet rs = ps.getGeneratedKeys()) {
rs.next();
uid = rs.getInt(1);
}
// 返回当前用户
return new User(uid, username, password);
}
} catch (SQLException exc) {
throw new RuntimeException(exc);
}
}
}
model
User
public class User {
public Integer uid;
public String username;
public String password;
public User(int uid, String username, String password) {
this.uid = uid;
this.username = username;
this.password = password;
}
// 检验用户名和密码合法性
public static boolean isLegal(String username, String password) {
if(username == null || password == null) {
return false;
}
if(username.trim().isEmpty() || password.trim().isEmpty()) {
return false;
}
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(username, user.username) && Objects.equals(password, user.password);
}
@Override
public int hashCode() {
return Objects.hash(username, password);
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
servlet
LoginServlet
login.html
发送 POST
请求,访问到 /login.do
// 登录操作
@WebServlet("/login.do")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 读取 用户名 + 密码
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
// 检验输入的合法性检查
if (!User.isLegal(username, password)) {
// 不合法重新登录
resp.sendRedirect("/login.html");
return;
}
System.out.println("DEBUG: username=" + username);
System.out.println("DEBUG: password=" + password);
// 2. 在所有用户之中查找匹配(用户名和密码都相等)的用户
UserDao userDao = UserDao.getUserDao();
User currentUser = userDao.selectOneByUsernameAndPassword(username, password);
// 3. 成功进行登录;失败跳回登录页
if (currentUser == null) {
// 登录失败
// 重定向 /login.html
resp.sendRedirect("/login.html");
return;
}
// 进行登录 —— 只有登录才能创建会话
HttpSession session = req.getSession(true);
// 这里的 key 设置任何字符串都可以,只要以后一直统一使用即可
session.setAttribute("currentUser", currentUser);
// 表示登录成功
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/plain");
PrintWriter writer = resp.getWriter();
writer.printf("欢迎 %s 使用我们的系统的", currentUser);
}
}
PublishServlet
用户URL+回车
发送 GET
请求,访问到 /publish.html
// 动态显示页面。登陆后才能显示内容
@WebServlet("/publish.html")
public class PublishServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取当前登录用户(从会话中读取)
User currentUser = null;
// 1.1 获取会话对象(session 对象)
HttpSession session = req.getSession(false); // 参数必须写 false,确保不新建 session 会话
if (session == null) {
// 说明之前没有会话,所以更不可能存在当前用户对象
resp.sendRedirect("/login.html");
return;
}
// 说明 session 对象存在,从 session 对象中拿 当前用户对象
// 当前用户对象是 LoginServlet 登录成功之后放到 session 对象中的
currentUser = (User) session.getAttribute("currentUser");
if (currentUser == null) {
// 说明 session 存在,但当前用户对象不存在
resp.sendRedirect("/login.html");
return;
}
// 获取到当前用户了,currentUser
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.printf("<h1>%s</h1>", currentUser);
}
}
RegisterServlet
register.html
发送 POST
请求,访问到 /register.do
// 注册操作
@WebServlet("/register.do")
public class RegisterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 读取 username + password
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
// 检验输入的合法性检查
if (!User.isLegal(username, password)) {
// 不合法重新注册
resp.sendRedirect("/register.html");
return;
}
// 2. 注册,向表中插入数据,通过 UserDao
UserDao userDao = UserDao.getUserDao();
User currentUser = userDao.insert(username, password);
// 再次跳到登录界面
resp.sendRedirect("/login.html");
}
}
util
DBUtil
public class DBUtil {
private static final DataSource dataSource;
static {
MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setUrl("jdbc:mysql:///lianxi?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("123456");
dataSource = mysqlDataSource;
}
public static Connection connection() throws SQLException {
return dataSource.getConnection();
}
}
webapp
WEB-INF
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="false">
</web-app>
login.html
<!DOCTYPE html>
<html lang="zh-hans">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="/login.do" method="post">
<input type="text" name="username">
<input type="password" name="password">
<button>登录</button>
<a href="./register.html">注册</a>
</form>
</body>
</html>
register.html
<!DOCTYPE html>
<html lang="zh-hans">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="/register.do" method="post">
<input type="text" name="username">
<input type="password" name="password">
<button>注册</button>
</form>
</body>
</html>
运行效果
-
注册
-
登录
-
用户登录后的动态页面
总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是JavaWeb的学习,在我们学会了session会话机制的条件下,我们可以做一个登录的小程序。之后的学习内容将持续更新!!!