tomcat+Servlet+JSP
现在已经不是主流了,可以学习一下,了解springboot框架的原理(悲,为什么要学过时的老东西)
不过可能在维护老应用时可能用到,小型项目也是一个不错的选择
教程视频
https://www.bilibili.com/video/BV1Sm4y1d76Q?spm_id_from=333.788.videopod.episodes&vd_source=837d4fe54a9ceb585673b377f66d35cb
tomcat
因为使用的java8,只能选用tomcat9 下载.zip文件后解压
创建环境变量,新建CATALINA_HOME
值为D:\development\apache-tomcat-9.0.97
然后在path中添加%CATALINA_HOME%\bin
然后浏览器输入 localhost:8080
新建项目
基于idea2022,新建jakarta ee 模板选择web application,应用程序服务器选择安装的tomcat版本,下一步,选择版本java ee 8
src/main/webapp/index.jsp就是我们启动的首页文件
然后我们编辑配置,添加配置,选择tomcat 本地
部署中添加工程目录
就可以运行了,注意要关闭之前启动的tomcat命令行,不然会端口占用,导致运行失败
Model
模型层,封装对象,让操作逻辑更加清晰
package model;
public class User {
private int userId;
private String username;
private String password; // 保存加密后的密码
private String salt; // 保存盐
// 构造函数
public User(int userId, String username, String password, String salt) {
this.userId = userId;
this.username = username;
this.password = password;
this.salt = salt;
}
// 获取用户ID
public int getUserId() {
return userId;
}
// 获取用户名
public String getUsername() {
return username;
}
}
Mysql
先创建数据库javaweb
连接数据库
package db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Database {
private static final String URL = "jdbc:mysql://localhost:3306/javaweb?useUnicode=true&characterEncoding=UTF-8";
private static final String USER = "root";
private static final String PASSWORD = "root";
public static Connection getConnection() throws SQLException {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("Database connected");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
DAO
DAO(Data Access Object) 是一种常用的设计模式,旨在将应用程序的业务逻辑与数据访问逻辑分离,从而提高代码的可维护性、可扩展性和测试性。
使用model层,将sql语句封装,提供接口给servlet
package db;
import model.User;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Base64;
public class UserDAO {
// 检查用户名是否已存在
public boolean isUsernameExists(String username) {
String sql = "SELECT COUNT(*) FROM users WHERE username = ?";
try (Connection conn = Database.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, username);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return rs.getInt(1) > 0;
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
// 注册用户
public boolean registerUser(String username, String password) {
if (isUsernameExists(username)) {
System.out.println("username already exists!");
return false;
}
// 生成盐并加密密码
String salt = generateSalt();
String encryptedPassword = encryptPassword(password, salt);
String sql = "INSERT INTO users (username, password, salt) VALUES (?, ?, ?)";
try (Connection conn = Database.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, username);
stmt.setString(2, encryptedPassword); // 只存储加密后的密码
stmt.setString(3, salt); // 单独存储盐
int rowsInserted = stmt.executeUpdate();
return rowsInserted > 0;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
// 用户登录
public User loginUser(String username, String password) {
String sql = "SELECT user_id, password, salt FROM users WHERE username = ?";
try (Connection conn = Database.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, username);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
int userId = rs.getInt("user_id");
String storedEncryptedPassword = rs.getString("password");
String salt = rs.getString("salt");
if (storedEncryptedPassword.equals(encryptPassword(password, salt))) {
System.out.println("login success!");
// 返回一个 User 对象,包含用户ID、用户名、盐和密码
return new User(userId, username, storedEncryptedPassword, salt);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("username or password incorrect!");
return null; // 登录失败返回 null
}
// 加密密码
private String encryptPassword(String password, String salt) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt.getBytes()); // 使用盐加密密码
byte[] hashedPassword = md.digest(password.getBytes());
return Base64.getEncoder().encodeToString(hashedPassword);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 生成盐
private String generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
return Base64.getEncoder().encodeToString(salt);
}
}
Servlet
ServLet = Server+Applet(小程序) ,一种在服务器端运行的小程序,用于处理来自jsp的请求,通过DAO操控数据库给出响应
package 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;
import java.io.PrintWriter;
@WebServlet(name = "LoginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
int id = Integer.parseInt(req.getParameter("id"));
String password = req.getParameter("pwd");
PrintWriter out = resp.getWriter();
out.println("账号"+id+"密码"+ password);
}
}
Jsp
Jsp = JavaServer Pages,用于绘制可视化界面
html的绘制
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
<link rel="stylesheet" type="text/css" href="styles/style.css">
</head>
<body>
<div class="container">
<h2>登录页面</h2>
<!-- 登录表单 -->
<form action="login" method="POST">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required/>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required/>
<input type="submit" value="登录"/>
<a href="register.jsp" class="button">注册</a>
</form>
</div>
</body>
</html>
css的封装
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f9;
color: #333;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
max-width: 400px;
width: 100%;
text-align: center;
}
h2 {
margin-bottom: 20px;
color: #2c3e50;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ddd;
border-radius: 4px;
}
input[type="submit"],
.button {
background-color: #3498db;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
text-transform: uppercase;
font-size: 14px;
}
input[type="submit"]:hover,
.button:hover {
background-color: #2980b9;
}