2010-03-26 5 views
34

Ho alcune classi che estendono una superclasse e nella JSP voglio mostrare alcuni attributi di queste classi. Voglio solo creare un JSP, ma non so in anticipo se l'oggetto ha un attributo o meno. Quindi ho bisogno di un'espressione JSTL o di un tag che controlli che l'oggetto che ho passato abbia questo attributo (simile all'operatore in javascript, ma nel server).Attributo di controllo esistente in 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> 

Come posso ottenere questo?

Grazie.

risposta

50

Fare uso di JSTL c:catch.

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

Sono solo io? Penso che questo sia un modo brutto per vedere se esiste una variabile o meno. È come catturare NullPointerException in java anziché? '(if! = null)' –

+5

@Shervin: è davvero un cattivo design. Ma questo è finora l'unico modo per raggiungere il requisito dispari. – BalusC

+0

@Shervin Asgari Penso che "se nullo" siano brutti. A meno che non lo fai api di terze parti. dovresti aver cura di tutte le eccezioni - pulisci modo. – magulla

1

Vuoi dire qualcosa di simile:

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

o altra variante

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

Se si tratta di una lista che si può fare

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

No, se faccio myObject.myAttribute e myObject non ha un getter per myAttribute, otterrò una PropertyNotFoundException. Non è lo stesso che un oggetto ha una proprietà con valore null che non ha questa proprietà. – Javi

+0

Ma in quale altro modo si dovrebbe accedere alla proprietà? Può essere accessibile solo attraverso i Getter per quanto ne so. Anche se la variabile è pubblica, credo che tu abbia bisogno di un getter. Perché non riesci a creare un getter? –

+3

La proprietà non è presente in ogni sottoclasse, quindi quando la proprietà è presente ho un getter per questo. Il problema è che non so quale delle sottoclassi passerà. – Javi

13

È possibile creare prontamente una funzione personalizzata per verificare la proprietà, come da vivin's blog post.

In breve, se si dispone già di vostra taglib la sua solo una questione di creare un metodo statico '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; 
    } 
} 

... e l'aggiunta di cinque righe al tuo 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> 

... e chiamando nel vostro JSP

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

Solo un più dettagliato di utilizzo (tipico?) di BalusC grande risposta

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

Come sottolineato da Shervin nei commenti di risposta di BalusC, questo non è probabilmente la soluzione più pulita, ma come ha risposto con BalusC "che è finora l'unico modo per raggiungere il requisito di strano".

Risorse

1

la risposta accettata può avere alcuni effetti collaterali quando voglio solo verificare se l'oggetto ha campo, ma fare non voglio emettere il valore del campo. Nei casi menzionati, utilizzo il colpo snippet:

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

sperare che questo aiuti.

Problemi correlati