在现代Web应用开发中,Servlet技术扮演着连接前端用户界面与后端业务逻辑及数据存储的核心角色,当用户在网页上填写并提交一个表单时,数据需要被安全、高效地传递到服务器端,并最终持久化到数据库中,本文将详细、系统地阐述如何通过Java Servlet技术实现这一完整流程,从前端表单设计到后端数据库操作的每一个关键环节。

第一步:构建前端HTML表单
一切始于用户交互,我们需要一个HTML表单来收集用户输入,这个表单有两个至关重要的属性:action 和 method。action 属性指定了表单数据提交的目标URL,这个URL将对应我们即将创建的Servlet。method 属性定义了数据提交的方式,通常使用 POST 方法,因为它能安全地传输大量数据,且不会在URL中暴露敏感信息。
假设我们正在创建一个用户注册页面,其表单代码可能如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">用户注册</title>
</head>
<body>
<h2>新用户注册</h2>
<form action="register" method="post">
<label for="username">用户名:</label><br>
<input type="text" id="username" name="username" required><br><br>
<label for="password">密码:</label><br>
<input type="password" id="password" name="password" required><br><br>
<label for="email">电子邮箱:</label><br>
<input type="email" id="email" name="email"><br><br>
<input type="submit" value="注册">
</form>
</body>
</html>
在这个例子中,表单数据将通过 POST 方法提交到相对路径 register,这意味着Servlet需要被配置来处理这个路径的请求。
第二步:准备后端环境与数据库
在编写Servlet之前,必须确保后端环境已经就绪,这包括:

- Web服务器/Servlet容器:Apache Tomcat,它是运行Servlet的容器。
- Java开发工具包 (JDK):用于编译Java代码。
- 数据库:MySQL 或 PostgreSQL。
- JDBC驱动:对应你所使用的数据库的Java驱动程序,它允许Java应用程序与数据库进行通信,你需要将相应的JAR文件(如
mysql-connector-java-xx.jar)添加到项目的WEB-INF/lib目录下。
在数据库中创建一个用于存储用户信息的表,以MySQL为例,可以执行以下SQL语句:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL, -- 密码应加密存储,此处为简化示例
email VARCHAR(100) UNIQUE,
registration_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
第三步:编写核心Servlet处理逻辑
这是整个流程的核心,Servlet需要接收HTTP请求,解析表单数据,并与数据库交互。
- 创建Servlet类:创建一个继承自
javax.servlet.http.HttpServlet的Java类。 - 重写
doPost方法:因为表单使用POST方法提交,所以我们需要重写doPost(HttpServletRequest request, HttpServletResponse response)方法来处理请求。 - 获取请求参数:使用
request.getParameter("parameterName")方法来获取表单中各个字段的值。parameterName必须与HTML表单中<input>标签的name属性完全一致。 - 数据库连接与操作:
- 加载驱动并建立连接:使用JDBC API加载驱动并获取数据库连接,为了代码的可维护性,通常会将数据库连接信息(URL、用户名、密码)封装在一个单独的工具类(如
DBUtil)中。 - 创建
PreparedStatement:这是防止SQL注入的关键步骤,不要直接拼接SQL字符串,应使用带占位符()的SQL语句,并通过PreparedStatement对象来设置参数。 - 执行更新:调用
executeUpdate()方法执行插入操作。 - 关闭资源:在
finally块中,务必关闭Connection、PreparedStatement等数据库资源,以避免资源泄露。
- 加载驱动并建立连接:使用JDBC API加载驱动并获取数据库连接,为了代码的可维护性,通常会将数据库连接信息(URL、用户名、密码)封装在一个单独的工具类(如
FormServlet.java 的核心代码示例如下:
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.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@WebServlet("/register")
public class FormServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 设置请求编码,防止中文乱码
request.setCharacterEncoding("UTF-8");
// 2. 获取表单参数
String username = request.getParameter("username");
String password = request.getParameter("password"); // 实际应用中应加密
String email = request.getParameter("email");
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 3. 获取数据库连接 (实际应用中应从连接池获取)
String url = "jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC";
String user = "your_username";
String pass = "your_password";
conn = DriverManager.getConnection(url, user, pass);
// 4. 创建PreparedStatement,防止SQL注入
String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password); // 存储前应进行哈希加密
pstmt.setString(3, email);
// 5. 执行插入操作
int count = pstmt.executeUpdate();
if (count > 0) {
// 6. 注册成功,重定向到成功页面
response.sendRedirect("success.html");
} else {
// 注册失败,重定向到失败页面
response.sendRedirect("error.html");
}
} catch (SQLException e) {
e.printStackTrace();
// 发生异常,重定向到错误页面
response.sendRedirect("error.html");
} finally {
// 7. 关闭资源
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
注意:上述代码使用了 @WebServlet("/register") 注解来配置Servlet的访问路径,这是现代Java EE推荐的方式,无需再配置 web.xml。

第四步:部署与测试
将项目打包成WAR文件,并部署到Tomcat服务器中,启动服务器后,在浏览器中访问 index.html,填写表单并提交,如果一切配置正确,数据将被成功插入到数据库的 users 表中,页面也会跳转到相应的成功或失败提示页面。
相关问答FAQs
| 问题 | 解答 |
|---|---|
什么是SQL注入,为什么说 PreparedStatement 是防止它的有效手段? |
SQL注入是一种代码注入技术,攻击者通过在Web应用的输入字段中“注入”恶意的SQL代码,来欺骗服务器执行非预期的数据库操作,在登录框输入 ' OR '1'='1,可能会绕过密码验证。PreparedStatement 通过预编译SQL语句并使用参数占位符()来有效防止SQL注入,当你调用 setString() 等方法设置参数时,驱动程序会自动对输入值进行转义和处理,确保它只被当作普通文本数据,而不会被解释为可执行的SQL代码的一部分,这从根本上杜绝了注入攻击的风险。 |
为什么在Servlet中直接创建JDBC连接(DriverManager.getConnection)是不推荐的做法? |
在Servlet中为每个请求都创建一个新的数据库连接是一种非常低效且危险的做法,主要原因有: 性能开销:建立数据库连接是一个耗时且消耗资源的过程,频繁创建和销毁连接会严重影响应用的性能和响应速度。 资源耗尽:在高并发场景下,如果大量请求同时创建连接,可能会迅速耗尽数据库的连接资源,导致应用崩溃。 最佳实践是使用数据库连接池(如HikariCP, C3P0, DBCP),连接池在应用启动时就创建一批数据库连接并维护起来,当Servlet需要连接时,直接从池中借用,用完后再归还给池,而不是关闭,这极大地减少了连接创建的开销,并能有效控制连接数量,保证应用的稳定性和高性能。 |