使用EL访问对象属性时需要进行null检查



在设置HTML之前,我曾使用JSTL来测试null值。但我最终得到了一个冗长的代码片段:

<c:choose>
    <c:when test="${data == null}">
        <input type ='text'>
        <input type ='text'>
        <input type ='text'>
        <input type ='text'>
        <input type ='text'>
    </c:when>
    <c:otherwise>
        <input type ='text' value= "${data.getAttribute1()}">
        <input type ='text' value= "${data.getAttribute2()}">
        <input type ='text' value= "${data.getAttribute3()}">
        <input type ='text' value= "${data.getAttribute4()}">
        <input type ='text' value= "${data.getAttribute5()}">
    </c:otherwise>
</c:choose>

但当我没有使用JSTL时,我仍然得到了正确的HTML页面,没有任何错误,当页面没有调用控制器时,似乎没有什么问题。代码如下:

<input type ='text' value= "${data.getAttribute1()}">
<input type ='text' value= "${data.getAttribute2()}">
<input type ='text' value= "${data.getAttribute3()}">
<input type ='text' value= "${data.getAttribute4()}">
<input type ='text' value= "${data.getAttribute5()}">

我检查null只是在浪费代码行吗?

当您通过EL读取属性时,不需要执行该检查。这就是所谓的EL.空安全设计功能

也就是说,这个答案旨在解释为什么会出现这种情况。为了背诵EL 3.0规范中关于操作员.的第1.6条(这反过来相当于操作员[]):

评估expr-a[expr-b]或expr-a[expr-b](params)

  • 将expr-a求值为值-a
  • 如果值-a为空
    • 如果expr-a[expr-b]是要解析的最后一个属性:
      • 如果表达式是值表达式并且ValueExpression.getValue(context)被调用以启动此表达式求值,则返回null
      • 否则,抛出PropertyNotFoundException[尝试取消对左值的null引用]
    • 否则,返回null

(重点是我的)。

由于表达式${data.getAttribute()}是一个使用参数化方法调用语法的值表达式,如果data == null为true,则null将作为data.getAttribute()求值的结果返回。一旦该EL表达式求值的输出为字符串,则根据EL 3.0规范的第1.23.2条,其值null将被强制为""(空字符串)。

还要注意,JSTL(用于构建类似<c:choose>的HTML的标签集)与EL(用于通过${expression}访问和操作应用程序数据的代码段)不相等。有关更多信息,请参阅我们的EL wiki页面。

最新更新