检查 JSP 中是不是存在属性

Posted

技术标签:

【中文标题】检查 JSP 中是不是存在属性【英文标题】: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>

我怎样才能得到这个?

谢谢。

【问题讨论】:

【参考方案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 所回答的那样,“这是迄今为止实现奇怪要求的唯一方法”。

资源

Evaluate empty or null JSTL c tags http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/set.html http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/catch.html

【讨论】:

【参考方案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 也不是空字符串)

以上是关于检查 JSP 中是不是存在属性的主要内容,如果未能解决你的问题,请参考以下文章

检查按钮是不是存在

如何检查 XmlAttributeCollection 中是不是存在属性?

如何简化检查 TypeScript 中是不是存在属性?

如何快速检查对象数组中是不是存在属性值

检查属性中是不是存在对象[重复]

如何检查 XML 中是不是存在特定属性?