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

Java Servlet无法向JSP传递数据,list为空抛出空指针异常求助

问题分析与解决方案

你的list为null的核心原因是Servlet的init方法执行失败,导致ServletContext中没有存入entries属性,同时代码里还有其他细节错误,以下是具体修复步骤:

1. 修复Scanner读取文件的错误

你当前用new Scanner(file)是把文件路径字符串当作输入内容,而非读取文件本身,这会导致读取逻辑完全错误,甚至抛出异常中断init方法,无法向ServletContext存入entries。

修改init方法中的Scanner初始化代码(记得导入java.io.File和java.io.FileNotFoundException):

public void init(ServletConfig config) throws ServletException {
    super.init(config);

    List<Question> entry = new ArrayList<>();
    ServletContext context = getServletContext();
    String file = getServletContext().getRealPath("/WEB-INF/Drivingtest.txt");
    Scanner in = null;

    try {
        in = new Scanner(new File(file));
        while (in.hasNextLine()){
            Question question = new Question();
            
            question.setDescription(in.nextLine()); 
            question.setAnswerA(in.nextLine());
            question.setAnswerB(in.nextLine());
            question.setAnswerC(in.nextLine());
            question.setCorrectAnswer(Integer.parseInt(in.nextLine()));
            
            // 跳过空行,先判断是否还有下一行,避免抛出NoSuchElementException
            if(in.hasNextLine()) {
                in.nextLine();
            }
            entry.add(question);
        }
        context.setAttribute("entries", entry);
    } catch (FileNotFoundException e) {
        throw new ServletException("无法找到试题文件: " + file, e);
    } finally {
        if(in != null) {
            in.close();
        }
    }
}

2. 确保Servlet初始化成功

检查以下关键点:

  • 确认/WEB-INF/Drivingtest.txt文件真实存在,注意文件名大小写(比如是否是DrivingTest.txt而非Drivingtest.txt)
  • 查看服务器日志,若存在FileNotFoundException或其他异常,说明init方法执行失败,Servlet无法完成初始化,自然不会向ServletContext存入entries

3. 修复JSP中的属性名大小写问题

Servlet中设置的request属性是SessionID(大写ID),但JSP中获取的是Sessionid(小写id),这会导致Sessionid永远为0,虽然不是list为null的直接原因,但会导致试题切换逻辑失效:

// 原JSP代码
if (request.getAttribute("Sessionid")!= null) {
    Sessionid = Integer.parseInt(request.getAttribute("Sessionid").toString())% list.size();
}

// 替换为:
if (request.getAttribute("SessionID")!= null) {
    Sessionid = Integer.parseInt(request.getAttribute("SessionID").toString()) % list.size();
}

4. 添加空值判断,避免NPE

在JSP中使用list之前先判断是否为null,防止直接调用list.get()触发空指针异常:

<%
ServletContext context = request.getServletContext();
List<Question> list = (List<Question>)context.getAttribute("entries");
int Sessionid = 0;
// 先判断list是否为空
if (list == null) {
%>
    <p>试题加载失败,请检查服务器日志</p>
<%
    return;
}
if (request.getAttribute("SessionID")!= null) {
    Sessionid = Integer.parseInt(request.getAttribute("SessionID").toString())% list.size();
}
%>

5. 修正Next链接的参数逻辑

当前Next链接传递的Sessionid参数未被Servlet读取,而是直接使用session中的id,导致链接切换逻辑无效,修改Servlet的doGet方法:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
    int id;
    HttpSession session = request.getSession();
    // 优先读取请求参数中的Sessionid
    String paramId = request.getParameter("Sessionid");
    if(paramId != null) {
        try {
            id = Integer.parseInt(paramId);
        } catch(NumberFormatException e) {
            id = 0;
        }
    } else {
        // 无参数时读取session中的id
        if (session.getAttribute("id") == null) {
            id = 0;
        } else {
            id = (int) session.getAttribute("id");
            id++;
        }
    }
    session.setAttribute("id", id);
    request.setAttribute("SessionID", id);
    request.getRequestDispatcher("DrivingTestBrowser.jsp").forward(request, response);
}

完成以上修复后,list应该能正常从ServletContext中获取,不会再出现null的情况。

内容的提问来源于stack exchange,提问作者Scels12

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:25:03