JSP页面直接输出实体对象空属性引发页面500报错实战案例
一、问题背景
传统Java Web项目开发中,大量业务页面使用JSP+EL表达式渲染数据。开发人员常直接通过${对象.属性}输出实体字段,忽略属性为null、实体对象本身为空的场景。
当实体对象为null,或目标属性未赋值时,EL表达式访问属性会触发NullPointerException,直接导致页面抛出500服务器异常,页面空白无法展示,线上出现用户访问页面报错问题。该问题无编译提示,仅运行时暴露,测试容易遗漏边界场景。
二、错误代码演示(坑点复现)
1. 后端Servlet赋值代码
importjavax.servlet.ServletException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;@WebServlet("/userInfo")publicclassUserServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{// 模拟查询无用户数据,对象直接赋值nullUseruser=null;request.setAttribute("user",user);request.getRequestDispatcher("user.jsp").forward(request,response);}}// 用户实体类classUser{privateStringusername;privateStringphone;// getter、setter省略publicStringgetUsername(){returnusername;}publicStringgetPhone(){returnphone;}}2. 存在BUG的JSP页面 user.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>用户信息</title> </head> <body> <%-- 未做空值判断,直接访问对象属性 --%> <p>用户名:${user.username}</p> <p>手机号:${user.phone}</p> </body> </html>运行异常现象
访问/userInfo后页面返回500错误,控制台抛出空指针异常:
java.lang.NullPointerException at org.apache.el.parser.AstValue.getValue(AstValue.java:167)原理:user对象为null,执行user.username时EL底层调用getter方法,空对象调用方法直接触发空指针。
同理,若user对象存在,但phone属性为null,单纯输出不会报错,但如果后续拼接、逻辑判断仍会衍生展示异常。
三、主流修复方案
方案1:EL内置empty关键字判空(推荐轻量方案)
使用empty判断对象是否为空,为空展示默认占位文本,避免访问空对象属性。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <c:if test="${empty user}"> <p>暂无用户信息</p> </c:if> <c:if test="${not empty user}"> <p>用户名:${user.username}</p> <p>手机号:${empty user.phone ? '未填写' : user.phone}</p> </c:if> </body> </html>需引入核心标签库:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>方案2:后端赋默认对象兜底
后端查询无数据时,不返回null,新建空实体对象,避免页面空对象访问:
Useruser=userService.getById(1);// 兜底处理if(user==null){user=newUser();user.setUsername("暂无数据");user.setPhone("无");}request.setAttribute("user",user);方案3:JSP脚本原生判空(不推荐,仅老旧项目兼容)
<% User user = (User)request.getAttribute("user"); String name = user == null ? "暂无用户" : user.getUsername(); %> <p>用户名:<%=name%></p>缺点:混合Java脚本与HTML,破坏页面分层,不利于维护。
四、项目开发规范避坑总结
- JSP使用EL渲染对象前,必须通过
empty判断对象非空,再读取内部属性; - 字符串属性输出时使用三元表达式设置默认值,避免页面空白;
- 后端查询数据接口统一兜底,无数据时返回空实体而非null;
- 项目统一引入JSTL标签库,禁止大量内嵌Java脚本;
- 单元测试覆盖数据为空、属性为null边界场景,提前拦截页面500异常。
五、线上风险说明
该异常会直接阻断页面渲染,用户无法查看页面内容,严重影响使用体验;批量列表场景下,单条数据对象为空会导致整个页面崩溃,而非单条数据隐藏,故障影响范围大。
海量精选技术文档和实战案例持续更新,敬请关注【风骏时光少年】