instanceof check in linguaggio di espressione EL

C’è un modo per eseguire instanceof check in EL?

Per esempio

  #{errorMessage1}   #{errorMessage2}  

È ansible confrontare Class#getName() o, forse meglio, Class#getSimpleName() in una String .

  #{errorMessage1}   #{errorMessage2}  

Si noti l’importanza di specificare Object#getClass() con notazione brace ['class'] perché la class è un valore letterale Java riservato che altrimenti genererebbe un’eccezione EL in EL 2.2+.

L’alternativa sicura al tipo consiste nell’aggiungere un public enum Type { A, B } insieme al public abstract Type getType() alla class di base comune del modello.

  #{errorMessage1}   #{errorMessage2}  

Tutti i valori non validi genererebbero qui un’eccezione EL durante il runtime in EL 2.2+.

Nel caso in cui usi OmniFaces , dalla versione 3.0 potresti usare #{of:isInstance()} .

  #{errorMessage1}   #{errorMessage2}  

Questo non funziona in EL . Usa il backing bean per questo:

 public class MyBean { public boolean getIsClassA() { if(model instanceof ClassA) { return true; } return false; } } 

Quindi eseguire il controllo chiamando il bean di supporto:

  #{errorMessage}  

Funziona:

 rendered="#{node.getClass().getSimpleName() == 'Logt_anno'}" 

Definisci una funzione statica come:

 public boolean isInstanceOf( Object obj, Class targetClass) { return targetClass.isInstance(obj); } 

Definisci una funzione EL personalizzata per esso e usala. Potremmo anche passare un nome di stringa e fare un forName() all’interno del metodo.

C’è un modo, vedi

JSF EL: instanceof riservato ma non ancora implementato?

Tuttavia, l’operatore instanceof non è ancora implementato, almeno in Mojarra 2.1. Si prega di votare per il bug qui:

http://java.net/jira/browse/JSP_SPEC_PUBLIC-113

La soluzione migliore attualmente è probabilmente quella di memorizzare il nome della class in un getter di backing bean invece di creare un metodo di test booleano per ogni class:

 public String getSelectedNodeClassName() { return selectedNode.getClass().getSimpleName(); } 

Quindi sarebbe un mix di soluzioni BalusC e Flash. Sarebbe comunque molto più leggibile in JSF rispetto a BalusC e in più assomiglia molto alla futura instanceof utilizzo da parte dell’operatore:

 rendered="#{nodeManager.selectedNodeClassName eq 'ChapterNode'}" 

Questo non produrrà un metodo per test di class sul bean di supporto come suggerito dal flash. Questo potrebbe essere più lento di quello di Flash.

Non molto elegante poiché mescola JSP EL e la syntax delle espressioni precedenti, ma non richiede alcun codice Java aggiuntivo:

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    <%-- Your logic here. --%>  

Potresti usare un bean helper per questo:

 @ManagedBean public class Helper { public boolean isInstance(Object bean, String fullyQualifiedClassName) { return Class.forName(fullyQualifiedClassName).isInstance(bean); } } 

Uso:

  #{errorMessage1}  

Questo ha il vantaggio che l’ereditarietà viene presa in considerazione e puoi testare per classi che non puoi modificare (entrambi gli svantaggi delle soluzioni di BalusC).

Se ti piace usare il nome semplice della class (e non temere le discussioni sul nome), puoi usare una mappa di ricerca che puoi compilare a mano o con uno scanner del percorso di class come org.reflections :

 @ManagedBean @ApplicationScoped public class Helper { private Map> classs = new Reflections("myrootpackage").getSubTypesOf(MyBaseClass.class).stream() .collect(Collectors.toMap(Class::getSimpleName, Function.identity())); public boolean isInstance(Object bean, String simpleClassName) { final Class c = this.classs.get(simpleClassName); return c != null && c.isInstance(bean); } } 

Potresti anche spostare la funzione di aiuto su un ELResolver:

 public class InstanceOfELResolver extends ELResolver { public Object invoke(final ELContext context, final Object base, final Object method, final Class[] paramTypes, final Object[] params) { if ("isInstanceOf".equals(method) && params.length == 1) { context.setPropertyResolved(true); try { return params[0] != null && Class.forName(params[0].toString()).isInstance(base); } catch (final ClassNotFoundException e) { return false; } } return null; } // ... All other methods with default implementation ... } 

Uso:

  #{errorMessage1}