如何在两个Java Servlet间传递数据库查询的用户数据
问题原因
你当前实现传值失败是三个核心错误:
- 登录成功后用
response.sendRedirect("profile.html")做客户端重定向,该方式会发起全新的HTTP请求,原request里存储的所有属性会全部丢失,且直接访问静态html文件根本不会触发ProfileServlet的逻辑,自然拿不到值。 - 把存储用户的
ArrayList定义为LogInServlet的成员变量,Servlet默认是单例模式,所有用户的请求都会共用这个列表,会出现不同用户登录数据串号的严重逻辑错误。 - 你注释掉的传值代码本身有bug:
set.getString(email)里传入的是用户输入的邮箱值作为列名,实际应该传入列名字符串"email",运行会直接抛SQL异常。
修复方案
- 删除LogInServlet的成员变量
List<User> users = new ArrayList<User>(),单用户登录场景只需要存储当前匹配到的单个User对象,不需要全局列表。 - 登录校验通过后,不要用重定向跳静态页面,改用
RequestDispatcher做服务端转发到ProfileServlet,服务端转发会复用同一个request对象,存储的属性可以直接传递到目标Servlet。 - ProfileServlet中拿到传递的User对象后再输出页面内容,静态html无法读取request中的动态数据,测试阶段可以直接在Servlet中拼接输出,后续可以把静态html改成jsp等动态模板做渲染。
- 如果需要跨多个请求保留用户登录状态,把User对象存入
HttpSession即可,不需要依赖转发传值。
修正后代码
LogInServlet 登录成功逻辑片段
把原来if(set.next())块里的内容替换为:
if(set.next()) { User user = new User(); user.setEmail(set.getString("email")); user.setPassword(set.getString("password")); user.setFirstName(set.getString("firstName")); user.setLastName(set.getString("lastName")); user.setDateOfBirth(set.getString("DOB")); // 将当前登录用户存入request作用域 request.setAttribute("currentUser", user); // 服务端转发到ProfileServlet,转发后直接return避免后续逻辑执行 RequestDispatcher rd = request.getRequestDispatcher("/ProfileServlet"); rd.forward(request, response); return; }
ProfileServlet 完整doGet逻辑
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=ISO-8859-1"); PrintWriter writer = response.getWriter(); // 取出转发传递的用户对象,做判空处理避免未登录直接访问时空指针 User currentUser = (User) request.getAttribute("currentUser"); if (currentUser == null) { response.sendRedirect("LogIn.html"); return; } // 测试传值用输出,后续可替换为profile.html的动态渲染逻辑 writer.write("<html><body>"); writer.write("验证传值成功:<br>"); writer.write("邮箱:" + currentUser.getEmail() + "<br>"); writer.write("姓名:" + currentUser.getFirstName() + " " + currentUser.getLastName() + "<br>"); writer.write("出生日期:" + currentUser.getDateOfBirth()); writer.write("</body></html>"); }
优化建议
- 数据库连接、PreparedStatement、ResultSet这些资源要放在finally块或者用try-with-resources语法关闭,避免中间抛出异常时资源泄漏。
- 禁止明文存储用户密码,后续要改成加盐哈希的方式存储。
- 正式实现登录功能时,校验通过后把用户信息存入Session:
request.getSession().setAttribute("currentUser", user),这样全站所有接口都可以直接获取当前登录用户信息,不需要依赖登录页转发传值。 - 要渲染profile.html的内容有两种实现方式:一是把profile.html改成jsp文件,直接在页面里读取request/session里的用户对象填充到对应标签位置;二是在ProfileServlet中读取静态html文件内容,替换掉对应占位符后输出给前端。
内容的提问来源于stack exchange,提问作者newbie-coder
相关产品推荐
相关产品推荐

