webentwicklung-frage-antwort-db.com.de

Das Überprüfungsattribut ist in JSP vorhanden

Ich habe einige Klassen, die eine Superklasse erweitern, und in der JSP möchte ich einige Attribute dieser Klassen zeigen. Ich möchte nur eine JSP erstellen, weiß aber nicht im Voraus, ob das Objekt ein Attribut hat oder nicht. Also brauche ich einen JSTL-Ausdruck oder ein Tag, das überprüft, ob das Objekt, das ich übergebe, dieses Attribut hat (ähnlich wie in operator in Javascript, aber auf dem Server).

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

Wie kann ich das bekommen?

Vielen Dank.

41
Javi

Nutzen Sie JSTL c:catch .

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

Sie können problemlos eine benutzerdefinierte Funktion erstellen, um nach der Eigenschaft zu suchen, wie in Vivins Blog-Post angegeben.

Kurz gesagt, wenn Sie bereits eine eigene TagLib haben, müssen Sie nur eine statische 'hasProperty'-Methode erstellen ...

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

... und füge deiner TLD fünf Zeilen hinzu ...

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

... und in Ihrer JSP aufrufen

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

Die akzeptierte Antwort kann einige Nebenwirkungen haben, wenn ich nur testen möchte, ob das Objekt ein Feld enthält, aber den Wert des Felds nicht ausgeben möchte. Im genannten Fall verwende ich das folgende Snippet:

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

hoffe das hilft.

2
Chaojun Zhong

Nur eine detailliertere (typische?) Verwendung von BalusC ist eine gute Antwort

<%--
  [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}

Wie Shervin in den Kommentaren zu BalusCs Antwort hervorhob, ist dies wahrscheinlich NICHT die sauberste Lösung, aber wie BalusC erwiderte, "ist dies bislang der einzige Weg, um die seltsame Anforderung zu erfüllen".

Ressourcen

2
Adrien Be

Meinen Sie so etwas:

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

oder eine andere Variante

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

Wenn es eine Liste ist, können Sie tun

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