javaweb小案例1
下面是一个超基础的 JavaWeb 登录 + 注册示例(使用 Servlet + JSP + MySQL)。它包含:
- 登录页面
login.jsp
- 注册页面
register.jsp
- 登录处理 Servlet
- 注册处理 Servlet
- 用户DAO 和数据库操作
- 数据表设计
一、数据库设计(MySQL)
CREATE DATABASE user_demo;
USE user_demo;CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) UNIQUE NOT NULL,password VARCHAR(50) NOT NULL
);
二、JSP 页面
login.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head><title>登录</title></head>
<body><h2>登录页面</h2><form action="login" method="post">用户名:<input type="text" name="username"/><br/>密码:<input type="password" name="password"/><br/><input type="submit" value="登录"/></form><p>还没有账号?<a href="register.jsp">去注册</a></p>
</body>
</html>
register.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head><title>注册</title></head>
<body><h2>注册页面</h2><form action="register" method="post">用户名:<input type="text" name="username"/><br/>密码:<input type="password" name="password"/><br/><input type="submit" value="注册"/></form>
</body>
</html>
三、Servlets
LoginServlet.java
@WebServlet("/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置编码(解决乱码)request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");String username = request.getParameter("username");String password = request.getParameter("password");UserDao dao = new UserDao();if (dao.login(username, password)) {response.getWriter().println("登录成功!");} else {response.getWriter().println("用户名或密码错误!");}}
}
RegisterServlet.java
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置编码(解决乱码)request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");String username = request.getParameter("username");String password = request.getParameter("password");UserDao dao = new UserDao();boolean result = dao.register(username, password);if (result) {response.getWriter().println("注册成功!<a href='login.jsp'>去登录</a>");} else {response.getWriter().println("注册失败,用户名可能已存在。");}}
}
四、UserDao.java
package com.zxy.demo;import java.sql.*;
import java.util.Enumeration;public class UserDao {private String jdbcurl = "jdbc:mysql://localhost:3306/user_demo?useUnicode=true&characterEncoding=UTF-8";private String jdbcUser = "root";private String jdbcPassword = "123456";// 静态代码块:尝试手动加载 MySQL 驱动,这就是重点!!!static {try {System.out.println("尝试加载 MySQL 驱动...");Class.forName("com.mysql.cj.jdbc.Driver");System.out.println(" MySQL 驱动加载成功!");} catch (ClassNotFoundException e) {System.out.println(" MySQL 驱动加载失败!");e.printStackTrace();}// 打印当前注册的 JDBC 驱动类(检查 SPI 机制是否生效)try {System.out.println("注册的 JDBC 驱动有:");Enumeration<Driver> drivers = DriverManager.getDrivers();while (drivers.hasMoreElements()) {Driver driver = drivers.nextElement();System.out.println("👉 " + driver.getClass().getName());}} catch (Exception e) {e.printStackTrace();}}private Connection getConnection() throws SQLException {System.out.println("尝试获取数据库连接...");return DriverManager.getConnection(jdbcurl, jdbcUser, jdbcPassword);}public boolean login(String username, String password) {String sql = "SELECT * FROM user WHERE username=? AND password=?";try (Connection conn = getConnection();PreparedStatement ps = conn.prepareStatement(sql)) {ps.setString(1, username);ps.setString(2, password);ResultSet rs = ps.executeQuery();return rs.next();} catch (SQLException e) {System.out.println(" 登录失败,SQL 异常:");e.printStackTrace();return false;}}public boolean register(String username, String password) {String sql = "INSERT INTO user(username, password) VALUES(?, ?)";try (Connection conn = getConnection();PreparedStatement ps = conn.prepareStatement(sql)) {ps.setString(1, username);ps.setString(2, password);int rows = ps.executeUpdate();System.out.println(" 注册执行完成,受影响行数:" + rows);return rows > 0;} catch (SQLException e) {System.out.println(" 注册失败,SQL 异常:");e.printStackTrace();return false;}}
}
🔧 配置说明
- 项目结构:建议使用 Maven Web 项目 + Tomcat
- 需要导入 mysql-connector-j(可以用 Maven):
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version>
</dependency>
解决bug:显示数据库连不上:
bug 最终原因是:
MySQL 驱动
mysql-connector-java.jar
虽然存在于项目中,但 Tomcat 实际运行时并没有加载到这个驱动。
为什么会发生?
用的是 Maven 管理项目 + IDEA 自动部署到 Tomcat,而这个组合有个常见坑点:
IDEA 默认使用 “exploded deployment”(爆炸式部署)
- 它 不会使用
target/practice.war
中的WEB-INF/lib/
- 而是直接用项目结构做软连接部署,结果就是:
驱动 jar 虽然在target
中,但运行时 classpath 并没有包含它
修复:
- 在
UserDao
里手动加载驱动Class.forName("com.mysql.cj.jdbc.Driver")
,主要就是这个!
让 JVM 强制注册 MySQL 驱动(绕过了 SPI 自动加载失败的问题)
- 最终部署方式正确了(可能是换了 war 部署或 IDEA 配置改了)
💡 总结一句话:
bug 是:JDBC 驱动没被正确加载进运行时环境(Tomcat 的 classpath),导致
DriverManager
无法识别 JDBC URL。
防止再次发生的建议:
建议 | 原因 |
---|---|
手动加 Class.forName(...) | 兼容所有 servlet 容器 |
避免 provided scope | 会导致依赖不被打进 war 包 |
检查 war 包是否包含 lib/mysql-xxx.jar | 确保构建没问题 |