2010-03-26 2 views
34

У меня есть несколько классов, которые расширяют суперкласс, а в JSP я хочу показать некоторые атрибуты этих классов. Я только хочу сделать один JSP, но я не знаю заранее, если объект имеет атрибут или нет. Поэтому мне нужно выражение JSTL или тег, который проверяет, что объект, который я передаю, имеет этот атрибут (похожий на оператора в javascript, но на сервере).Атрибут проверки существует в JSP

<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> 

Как это получить?

Спасибо.

ответ

50

Воспользоваться JSTL c:catch.

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

Это только я? Я думаю, что это уродливый способ увидеть, существует ли переменная или нет. Это похоже на ловкое исключение NullPointerException в java вместо? '(if! = null)' –

+5

@ Шервин: это действительно плохой дизайн. Но это пока единственный способ достичь нечетного требования. – BalusC

+0

@Shervin Asgari Я думаю, что «если нуль» уродливый. Если вы не делаете это сторонним api. вы должны позаботиться обо всех исключениях - путь чище. – magulla

1

ли вы имеете в виду что-то вроде этого:

<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}"> 
+3

Нет, если я делаю myObject.myAttribute, а myObject не имеет getter для myAttribute, я получу PropertyNotFoundException. Это не то же самое, что объект имеет свойство с нулевым значением, которое не имеет этого свойства. – Javi

+0

Но как еще вы должны получить доступ к собственности? Насколько мне известно, доступ к нему возможен только через геттеры. Даже если переменная открыта, я считаю, что вам нужен геттер. Почему вы не можете создать геттер? –

+3

Свойство отсутствует в каждом подклассе, поэтому, когда свойство присутствует, у меня есть геттер. Проблема в том, что я не знаю, какой из подклассов будет передан. – Javi

13

Вы можете легко создать пользовательскую функцию для проверки имущества, согласно 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> 
2

Просто более детального (типичное?) использование 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 «что до сих пор единственный способ достижения нечетное требование».

Ресурсы

1

принятый ответ может иметь некоторые побочные эффекты, когда я просто хочу, чтобы проверить, если объект имеет поле, но сделать не хотите выводить значение поля. В упомянутых случаях я использую удар фрагмента:

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

надеюсь, что это поможет.

Смежные вопросы