JSP页面直接输出实体对象空属性引发页面500报错实战案例

JSP页面直接输出实体对象空属性引发页面500报错实战案例

一、问题背景

传统Java Web项目开发中,大量业务页面使用JSP+EL表达式渲染数据。开发人员常直接通过${对象.属性}输出实体字段,忽略属性为null、实体对象本身为空的场景。 当实体对象为null,或目标属性未赋值时,EL表达式访问属性会触发NullPointerException,直接导致页面抛出500服务器异常,页面空白无法展示,线上出现用户访问页面报错问题。该问题无编译提示,仅运行时暴露,测试容易遗漏边界场景。

二、错误代码演示(坑点复现)

1. 后端Servlet赋值代码

java 复制代码
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/userInfo")
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 模拟查询无用户数据,对象直接赋值null
        User user = null;
        request.setAttribute("user", user);
        request.getRequestDispatcher("user.jsp").forward(request, response);
    }
}

// 用户实体类
class User {
    private String username;
    private String phone;
    // getter、setter省略
    public String getUsername() { return username; }
    public String getPhone() { return phone; }
}

2. 存在BUG的JSP页面 user.jsp

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错误,控制台抛出空指针异常:

less 复制代码
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判断对象是否为空,为空展示默认占位文本,避免访问空对象属性。

jsp 复制代码
<%@ 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>

需引入核心标签库:

jsp 复制代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

方案2:后端赋默认对象兜底

后端查询无数据时,不返回null,新建空实体对象,避免页面空对象访问:

java 复制代码
User user = userService.getById(1);
// 兜底处理
if(user == null){
    user = new User();
    user.setUsername("暂无数据");
    user.setPhone("无");
}
request.setAttribute("user", user);

方案3:JSP脚本原生判空(不推荐,仅老旧项目兼容)

jsp 复制代码
<%
    User user = (User)request.getAttribute("user");
    String name = user == null ? "暂无用户" : user.getUsername();
%>
<p>用户名:<%=name%></p>

缺点:混合Java脚本与HTML,破坏页面分层,不利于维护。

四、项目开发规范避坑总结

  1. JSP使用EL渲染对象前,必须通过empty判断对象非空,再读取内部属性;
  2. 字符串属性输出时使用三元表达式设置默认值,避免页面空白;
  3. 后端查询数据接口统一兜底,无数据时返回空实体而非null;
  4. 项目统一引入JSTL标签库,禁止大量内嵌Java脚本;
  5. 单元测试覆盖数据为空、属性为null边界场景,提前拦截页面500异常。

五、线上风险说明

该异常会直接阻断页面渲染,用户无法查看页面内容,严重影响使用体验;批量列表场景下,单条数据对象为空会导致整个页面崩溃,而非单条数据隐藏,故障影响范围大。

海量精选技术文档和实战案例持续更新,敬请关注【风骏时光少年】

相关推荐
IT_陈寒2 小时前
Python里这个赋值坑,连老司机都能翻车
前端·人工智能·后端
Hyyy3 小时前
什么是bun?和pnpm有什么区别
前端·面试·bun
IT_陈寒16 小时前
Vue这个坑我跳了两次,原来问题出在这
前端·人工智能·后端
kyriewen16 小时前
我用 50 行代码重写了 React Router 核心,终于搞懂了前端路由原理
前端·javascript·react.js
WebInfra17 小时前
Rspack 2.1 发布:React Compiler 提速 10 倍!
前端
李明卫杭州17 小时前
CSS 媒体查询详解:一文掌握响应式设计的核心技术
前端
lichenyang45318 小时前
从 H5 按钮到 OpenHarmony 能力调用:我如何理解 ASCF 的运行链路
前端
下家18 小时前
我放弃了 Vue/React,选择自研框架
前端·前端框架
Asize19 小时前
HTML5 Canvas 基础:从按帧动画到 ECharts 数据可视化
前端·javascript·canvas