JSP页面展示数据时出现NullPointerException问题排查与解决
问题描述
基于NetBeans IDE、Tomcat服务器和MySQL数据库开发的Web应用,在JSP页面展示数据列表时出现异常:直接访问JSP页面报错,但通过Servlet访问则功能正常。
相关代码
DA层数据查询方法
public List<Automoveis> consultarTodosAutomoveis() throws ClassNotFoundException, SQLException { Connection con = Conexao.getConexao(); PreparedStatement comando = con.prepareStatement("select * from automoveis;"); ResultSet rs = comando.executeQuery(); List<Automoveis> lauto = new ArrayList<Automoveis>(); int cont = 0; while(rs.next()) { Automoveis auto = new Automoveis(); auto.setIdAuto(rs.getInt("idAuto")); auto.setMarca(rs.getString("marca")); auto.setModelo(rs.getString("modelo")); auto.setCor(rs.getString("cor")); auto.setImportado(rs.getString("importado")); auto.setNumeroRodas(rs.getInt("numeroRodas")); auto.setPreco(rs.getDouble("preco")); lauto.add(auto); cont++; } System.out.println("Cont..: " + cont); con.close(); return lauto; }
Servlet数据转发代码
try (PrintWriter out = response.getWriter()) { MetodosDAO mdao = new MetodosDAO(); try { List<Automoveis> lauto = mdao.consultarTodosAutomoveis(); request.setAttribute("lauto", lauto); request.getRequestDispatcher("resultadoconsultartodsautomoveis.jsp").forward(request, response); } catch (ClassNotFoundException | SQLException ex) { System.out.println("Error: " + ex.getMessage()); } }
JSP展示页面(resultadoconsultartodsautomoveis.jsp)
<%@page import="java.util.List"%> <%@page import="model.Automoveis"%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>Result of Consulting All Automoveis</h1> <% List<Automoveis> lauto = (List<Automoveis>) request.getAttribute("lauto"); %> <% for (Automoveis auto : lauto) { %> Id: <%= auto.getIdAuto() %><br> Brand: <%= auto.getMarca() %><br><br> Model: <%= auto.getIdAuto() %><br><br> Color: <%= auto.getCor() %><br><br> Imported: <%= auto.getImportado() %><br><br> Number of Wheels: <%= auto.getNumeroRodas() %><br><br> Price: <%= auto.getPreco() %><br><br> <% } %> </body> </html>
错误信息
直接访问resultadoconsultarautomoveis.jsp时触发以下异常:
HTTP Status 500 – Internal Server Error Type Exception Report Message An exception occurred processing [/resultadoconsultartodsautomoveis.jsp] at line [21] Description The server encountered an unexpected condition that prevented it from fulfilling the request. Exception org.apache.jasper.JasperException: An exception occurred processing [/resultadoconsultartodsautomoveis.jsp] at line [21] ... java.lang.NullPointerException: Cannot invoke "java.util.List.iterator()" because "lauto" is null ...
原因分析与修复方案
错误原因
直接访问JSP时,请求未经过Servlet处理流程,request对象中没有被设置lauto属性,导致request.getAttribute("lauto")返回null。当JSP尝试遍历这个空列表时,就会触发空指针异常。而通过Servlet访问时,Servlet已经完成数据查询并将列表存入请求属性,因此JSP能正常获取数据。
修复方案
方案1:JSP添加空值判断
在遍历列表前先检查lauto是否为空,避免空指针,同时修正原JSP中Model行的错误(误用了getIdAuto(),应改为getModelo()):
<%@page import="java.util.List"%> <%@page import="model.Automoveis"%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>Result of Consulting All Automoveis</h1> <% List<Automoveis> lauto = (List<Automoveis>) request.getAttribute("lauto"); %> <% if (lauto != null && !lauto.isEmpty()) { %> <% for (Automoveis auto : lauto) { %> Id: <%= auto.getIdAuto() %><br> Brand: <%= auto.getMarca() %><br><br> Model: <%= auto.getModelo() %><br><br> Color: <%= auto.getCor() %><br><br> Imported: <%= auto.getImportado() %><br><br> Number of Wheels: <%= auto.getNumeroRodas() %><br><br> Price: <%= auto.getPreco() %><br><br> <% } %> <% } else { %> <p>无数据或页面被直接访问</p> <% } %> </body> </html>
方案2:强制通过Servlet访问JSP
在JSP开头添加逻辑,若lauto不存在则重定向到Servlet,确保请求经过数据查询流程:
<%@page import="java.util.List"%> <%@page import="model.Automoveis"%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <% List<Automoveis> lauto = (List<Automoveis>) request.getAttribute("lauto"); if (lauto == null) { // 替换为实际的Servlet访问路径 response.sendRedirect("你的Servlet映射路径"); return; } %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>Result of Consulting All Automoveis</h1> <% for (Automoveis auto : lauto) { %> Id: <%= auto.getIdAuto() %><br> Brand: <%= auto.getMarca() %><br><br> Model: <%= auto.getModelo() %><br><br> Color: <%= auto.getCor() %><br><br> Imported: <%= auto.getImportado() %><br><br> Number of Wheels: <%= auto.getNumeroRodas() %><br><br> Price: <%= auto.getPreco() %><br><br> <% } %> </body> </html>
额外优化建议
- 资源自动关闭:DAO层使用try-with-resources自动关闭数据库连接、Statement和ResultSet,避免资源泄漏:
public List<Automoveis> consultarTodosAutomoveis() throws ClassNotFoundException, SQLException { try (Connection con = Conexao.getConexao(); PreparedStatement comando = con.prepareStatement("select * from automoveis;"); ResultSet rs = comando.executeQuery()) { List<Automoveis> lauto = new ArrayList<>(); int cont = 0; while (rs.next()) { Automoveis auto = new Automoveis(); auto.setIdAuto(rs.getInt("idAuto")); auto.setMarca(rs.getString("marca")); auto.setModelo(rs.getString("modelo")); auto.setCor(rs.getString("cor")); auto.setImportado(rs.getString("importado")); auto.setNumeroRodas(rs.getInt("numeroRodas")); auto.setPreco(rs.getDouble("preco")); lauto.add(auto); cont++; } System.out.println("Cont..: " + cont); return lauto; } }
- 使用JSTL+EL替代脚本:让JSP页面更简洁易维护:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>Result of Consulting All Automoveis</h1> <c:if test="${not empty lauto}"> <c:forEach items="${lauto}" var="auto"> Id: ${auto.idAuto}<br> Brand: ${auto.marca}<br><br> Model: ${auto.modelo}<br><br> Color: ${auto.cor}<br><br> Imported: ${auto.importado}<br><br> Number of Wheels: ${auto.numeroRodas}<br><br> Price: ${auto.preco}<br><br> </c:forEach> </c:if> <c:if test="${empty lauto}"> <p>无数据或页面被直接访问</p> </c:if> </body> </html>
内容的提问来源于stack exchange,提问作者Vitor Ferreira
相关产品推荐
相关产品推荐

