JSP无法从Servlet接收List数据问题求助
问题描述
我正在开发一个通过Servlet向JSP传递数据的项目。Servlet从数据库获取数据并存储到List<Integer>中(值为2、3),将其存入HttpSession的"partidas"属性后重定向到ListadoPartidas.jsp。在JSP中,使用EL表达式${partidas}能正常显示2,3,但通过脚本段<% List<Integer> partidas = (List<Integer>) request.getAttribute("partidas"); %>无法获取该数据,无法生成预期的页面内容。
Servlet代码
import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.sql.*; import java.util.*; public class PartidasAMedias extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Connection con; Statement st; ResultSet rs; PrintWriter out; String SQL, Nombre; int IdUsu, Estado; List<Integer> partidas = new ArrayList<Integer>(); try { Nombre = req.getParameter("nombreRecogido"); System.out.println("Nombre: " + Nombre); Class.forName("com.mysql.cj.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost/cuatroenraya", "root", ""); st = con.createStatement(); SQL = "SELECT IdUsuario FROM usuarios WHERE Nombre ='" + Nombre + "'"; rs = st.executeQuery(SQL); if (rs.next()) { System.out.println("2." + rs.getInt("IdUsuario")); IdUsu = rs.getInt("IdUsuario"); SQL = "SELECT IdPartida, Estado FROM partidas WHERE Creador ='" + IdUsu + "' OR Invitado = '" + IdUsu + "'"; rs = st.executeQuery(SQL); if (rs.next()) { Estado = rs.getInt("Estado"); while (rs.next()) { if (Estado == 1) { int idPartida = rs.getInt("IdPartida"); System.out.println("3." + idPartida); partidas.add(rs.getInt("IdPartida")); System.out.println("Partida agregada: " + rs.getInt("IdPartida")); } } System.out.println("4."+ partidas); HttpSession session = req.getSession(true); //session.setAttribute("partidas", partidas); req.getSession().setAttribute("partidas", partidas); System.out.println("Redirigiendo a ListadoPartidas.jsp con partidas: " + partidas); res.sendRedirect("ListadoPartidas.jsp"); } else { res.sendRedirect("zSinPartidas.html"); } } rs.close(); st.close(); con.close(); } catch (Exception e) { System.err.println(e); } } }
ListadoPartidas.jsp代码
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> <%@ page import="java.util.List" %> <!DOCTYPE html> <html lang="es" dir="ltr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Partidas en curso</title> </head> <body> ${partidas} <% List<Integer> partidas = (List<Integer>) request.getAttribute("partidas"); if (partidas != null && !partidas.isEmpty()) { %> <table> <thead> <tr> <th>ID Partida</th> </tr> </thead> <tbody> <% for (Integer idPartida : partidas) { %> <tr> <td> <%= idPartida %> </td> </tr> <% } %> </tbody> </table> <% } else { %> <p>No hay partidas a medias</p> <% } %> </body> </html>
解决方案
核心问题
数据被存储在HttpSession作用域中,但JSP脚本段使用request.getAttribute("partidas")仅从当前请求作用域查找数据,自然无法获取;而EL表达式${partidas}会自动按Page→Request→Session→Application的顺序遍历所有作用域,因此能找到Session中的数据。
修复步骤
1. 修改JSP脚本段,从Session中获取数据
将脚本段中的request.getAttribute替换为session.getAttribute:
<% List<Integer> partidas = (List<Integer>) session.getAttribute("partidas"); %>
2. 修正Servlet中的数据库查询逻辑
当前代码存在三个关键问题:
- 查询结果丢失第一条数据:先调用
rs.next()判断是否有数据,随后直接获取Estado,再进入while(rs.next())会跳过第一条记录,导致集合少一条数据。修正后的结果遍历逻辑:rs = st.executeQuery(SQL); // 去掉多余的if(rs.next()),直接用while遍历所有结果 while (rs.next()) { Estado = rs.getInt("Estado"); if (Estado == 1) { int idPartida = rs.getInt("IdPartida"); System.out.println("3." + idPartida); partidas.add(idPartida); System.out.println("Partida agregada: " + idPartida); } } - SQL注入风险:直接拼接参数到SQL语句中,容易被注入攻击。建议使用
PreparedStatement替代Statement:// 替换原有的Statement为PreparedStatement SQL = "SELECT IdUsuario FROM usuarios WHERE Nombre = ?"; PreparedStatement pst = con.prepareStatement(SQL); pst.setString(1, Nombre); rs = pst.executeQuery(); - 资源泄漏问题:数据库连接、Statement、ResultSet的关闭逻辑应放在
finally块中,避免异常时资源无法释放:} catch (Exception e) { System.err.println(e); } finally { try { if (rs != null) rs.close(); if (st != null) st.close(); if (con != null) con.close(); } catch (SQLException e) { e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者Carmen
相关产品推荐
相关产品推荐

