如何在JSP文本框中仅显示当前登录用户的个人数据?
解决JSP文本框仅显示当前登录用户信息的问题
你现在遇到的问题是,登录后changePersonalData.jsp会把数据库里所有用户的信息都显示出来,而你只想要展示当前登录用户的数据。这个问题的核心在于两个点:一是你的JSP没有利用登录时存在Session里的用户标识,二是SQL查询没有添加针对当前用户的过滤条件。
问题分析
- 你的
LoginServlet已经在登录成功后把当前用户的username存入了Session,但changePersonalData.jsp完全没有用到这个标识; - JSP里的SQL语句是
select * from users,会查询所有用户的数据,再通过while循环输出每一个用户的表单,这就是为什么会显示所有用户信息的原因。
解决方案
我们可以通过以下步骤修改代码,实现仅显示当前登录用户的信息:
1. 优化LoginServlet(可选但推荐)
首先,你的LoginServlet存在SQL注入风险,而且可以在登录时直接把用户的完整信息存入Session,这样JSP不用重复查询数据库,效率更高。修改后的LoginServlet关键代码如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String username = request.getParameter("username"); String password = request.getParameter("password"); try { Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/e-book", "root", "root"); // 用PreparedStatement防止SQL注入 String sql = "select * from users where username = ? and password = ?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, username); pstmt.setString(2, password); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { HttpSession session = request.getSession(); // 将当前用户的所有信息存入Session session.setAttribute("username", rs.getString("username")); session.setAttribute("firstname", rs.getString("first_name")); session.setAttribute("lastname", rs.getString("last_name")); session.setAttribute("password", rs.getString("password")); response.sendRedirect("mainMenu.jsp"); } else { out.println("Wrong id and/or password"); } con.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } }
2. 修改changePersonalData.jsp
如果选择上面的方式,JSP可以直接从Session取数据,不用再连接数据库,代码会更简洁:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page import="javax.servlet.http.HttpSession" %> <% // 获取当前登录用户的Session HttpSession session = request.getSession(false); if(session == null || session.getAttribute("username") == null) { // 如果未登录,重定向到登录页面 response.sendRedirect("login.jsp"); return; } %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Change</title> </head> <body> <form method="post" action="ChangePersonalDataServlet"> <table align="left"> <tr> <td>First name</td> <td><input type="text" name="firstname" value="<%= session.getAttribute("firstname") %>"></td> </tr> <tr> <td>Last name</td> <td><input type="text" name="lastname" value="<%= session.getAttribute("lastname") %>"></td> </tr> <tr> <td>User name</td> <td><input type="text" name="username" value="<%= session.getAttribute("username") %>"></td> </tr> <tr> <td>Password</td> <td><input type="password" name="password" value="<%= session.getAttribute("password") %>"></td> </tr> <tr> <td></td> <td><input type="submit" value="Change"></td> </tr> </table> </form> </body> </html>
如果你还是希望在JSP中查询数据库(不推荐,因为JSP应该尽量避免业务逻辑),可以修改JSP的查询逻辑,利用Session中的username过滤数据:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@page import="java.sql.DriverManager"%> <%@page import="java.sql.ResultSet"%> <%@page import="java.sql.PreparedStatement"%> <%@page import="java.sql.Connection"%> <%@ page import="javax.servlet.http.HttpSession" %> <% HttpSession session = request.getSession(false); String currentUsername = null; if(session != null) { currentUsername = (String) session.getAttribute("username"); } if(currentUsername == null) { response.sendRedirect("login.jsp"); return; } String driver = "com.mysql.jdbc.Driver"; String connectionUrl = "jdbc:mysql://localhost:3306/"; String database = "e-book"; String userid = "root"; String password = "root"; try { Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } Connection connection = null; PreparedStatement pstmt = null; ResultSet resultSet = null; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Change</title> </head> <body> <form method="post" action="ChangePersonalDataServlet"> <table align="left"> <% try { connection = DriverManager.getConnection(connectionUrl + database, userid, password); String sql = "select * from users where username = ?"; pstmt = connection.prepareStatement(sql); pstmt.setString(1, currentUsername); resultSet = pstmt.executeQuery(); // 因为是单个用户,用if而不是while if(resultSet.next()) { %> <tr> <td>First name</td> <td><input type="text" name="firstname" value="<%=resultSet.getString("first_name")%>"></td> </tr> <tr> <td>Last name</td> <td><input type="text" name="lastname" value="<%=resultSet.getString("last_name")%>"></td> </tr> <tr> <td>User name</td> <td><input type="text" name="username" value="<%=resultSet.getString("username")%>"></td> </tr> <tr> <td>Password</td> <td><input type="password" name="password" value="<%=resultSet.getString("password")%>"></td> </tr> <% } connection.close(); } catch (Exception e) { e.printStackTrace(); } %> <tr> <td></td> <td><input type="submit" value="Change"></td> </tr> </table> </form> </body> </html>
重要提醒
- 永远不要用
Statement拼接SQL语句,这会导致SQL注入漏洞,一定要用PreparedStatement; - JSP中尽量避免写数据库操作等业务逻辑,最好把这些逻辑放到Servlet或者Service层,遵循MVC的设计思想;
- 密码不要明文存储在数据库和Session中,应该用哈希算法(比如MD5、SHA-256)加密后存储。
内容的提问来源于stack exchange,提问作者Neo Cortex
相关产品推荐
相关产品推荐

