You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:48:17