【问题标题】:Checking attribute exists in JSP检查 JSP 中是否存在属性
【发布时间】:2011-02-01 03:04:34
【问题描述】:

我有一些扩展超类的类,在 JSP 中我想展示这些类的一些属性。我只想做一个JSP,但是事先不知道对象有没有属性。所以我需要一个 JSTL 表达式或一个标签来检查我传递的对象是否具有此属性(类似于 javascript 中的 in 运算符,但在服务器中)。

<c:if test="${an expression which checks if myAttribute exists in myObject}">
    <!-- Display this only when myObject has the atttribute "myAttribute" -->
    <!-- Now I can access safely to "myAttribute" -->
    ${myObject.myAttribute}
</C:if>

我怎样才能得到这个?

谢谢。

【问题讨论】:

    标签: jsp jstl jsp-tags


    【解决方案1】:

    利用 JSTL c:catch

    <c:catch var="exception">${myObject.myAttribute}</c:catch>
    <c:if test="${not empty exception}">Attribute not available.</c:if>
    

    【讨论】:

    • 只有我一个人吗?我认为这是查看变量是否存在的一种丑陋方式。就像在 java 中捕获 NullPointerException 而不是? (if!=null)
    • @Shervin:这确实是一个糟糕的设计。但到目前为止,这是实现奇怪要求的唯一方法。
    • @Shervin Asgari 我认为“如果为空”很难看。除非你做第三方 api。您应该处理所有异常 - 方式更清洁。
    • @ShervinAsgari - 你是对的,但是 JSP/JSTL 经常出现“漂亮”解决方案不可用、冗长或极其迂回的情况(参见 sbk 的回答,它创建了一个 新标签库)。尝试做一个正确的if/else-if 块是另一个很好的例子。
    • 如果要检查列表属性是否为空,请使用${list != null},因为${not empty list}在列表为空列表时返回true。
    【解决方案2】:

    您可以根据vivin's blog post 轻松创建自定义函数来检查属性。

    简而言之,如果您已经拥有自己的 taglib,只需创建一个静态的“hasProperty”方法...

    import java.beans.PropertyDescriptor;
    import org.apache.commons.beanutils.PropertyUtils;
    
    ...
    
    public static boolean hasProperty(Object o, String propertyName) {
        if (o == null || propertyName == null) {
            return false;
        }
        try
        {
          return PropertyUtils.getPropertyDescriptor(o, propertyName) != null;
        }
        catch (Exception e)
        {
          return false;
        }
    }
    

    ...并在您的 TLD 中添加五行...

    <function>
        <name>hasProperty</name>
        <function-class>my.package.MyUtilClass</function-class>
        <function-signature>boolean hasProperty(java.lang.Object,
            java.lang.String)
        </function-signature>
    </function>
    

    ...并在您的 JSP 中调用它

    <c:if test="${myTld:hasProperty(myObject, 'myAttribute')}">
      <c:set var="foo" value="${myObject.myAttribute}" />
    </c:if>
    

    【讨论】:

      【解决方案3】:

      当我只想测试对象是否有字段但不想输出字段的值时,接受的答案可能会产生一些副作用。在上述情况下,我使用下面的 sn-p:

       <c:catch var="exception">
              <c:if test="${object.class.getDeclaredField(field) ne null}">            
              </c:if>
       </c:catch>
      

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        BalusC 的一个更详细的(典型的?)用法很好的答案

        <%--
          [1] sets a default value for variable "currentAttribute"
          [2] check if myObject is not null
          [3] sets variable "currentAttribute" to the value of what it contains
          [4] catches "property not found exception" if any
               - if exception thrown, it does not output anything
               - if not exception thrown, it outputs the value of myObject.myAttribute
        
        --%>
        <c:set var="currentAttribute" value="" /> <%-- [1] --%>
        <c:if test="${not empty myObject}"> <%-- [2] --%>
            <c:set var="currentAttribute"> <%-- [3] --%>
                <c:catch var="exception">${myObject.myAttribute}</c:catch> <%-- [4] --%>
            </c:set>
        </c:if>
        
        <%-- use the "currentAttribute" variable without worry in the rest of the code --%>
        currentAttribute is now equal to: ${currentAttribute}
        

        正如 Shervin 在 BalusC 的回答中指出的那样,这可能不是最干净的解决方案,但正如 BalusC 所回答的那样,“这是迄今为止实现奇怪要求的唯一方法”。

        资源

        【讨论】:

          【解决方案5】:

          你的意思是这样的:

          <c:if test="${not null myObject.myAttribute}">
             <!-- Now I can access safely to "myAttribute" -->
          </C:if>
          

          或其他变体

          <c:if test="${myObject.myAttribute != null}">
             <!-- Now I can access safely to "myAttribute" -->
          </C:if>
          

          如果是你可以做的列表

          <c:if test="#{not empty myObject.myAttribute}">
          

          【讨论】:

          • 不,如果我执行 myObject.myAttribute 并且 myObject 没有 myAttribute 的 getter,我将得到 PropertyNotFoundException。一个对象有一个 null 值的属性和它没有这个属性是不一样的。
          • 但是您还应该如何访问该属性?据我所知,它只能通过吸气剂访问。即使变量是公开的,我相信您也需要一个吸气剂。为什么不能只创建一个吸气剂?
          • 该属性并不存在于每个子类中,因此当该属性存在时,我有一个 getter。问题是我不知道要传递哪个子类。
          • @Shervin 我相信您的答案是“仅”检查属性是否已设置(不是 null 也不是空字符串)
          猜你喜欢
          • 1970-01-01
          • 2021-04-22
          • 1970-01-01
          • 1970-01-01
          • 2018-02-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多