Instanceof проверка на языке выражения EL

Есть ли способ выполнить проверку instanceof в EL?

например.

<h:link rendered="#{model instanceof ClassA}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{model instanceof ClassB}">      
    #{errorMessage2}
</h:link>

Ответы

Ответ 1

Вы можете сравнить Class#getName() или, может быть, лучше, Class#getSimpleName() до String.

<h:link rendered="#{model['class'].simpleName eq 'ClassA'}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{model['class'].simpleName eq 'ClassB'}">      
    #{errorMessage2}
</h:link>

Обратите внимание на важность указания Object#getClass() с нотной привязкой ['class'], потому что class является зарезервированным литералом Java, который в противном случае выбрал бы исключение EL в EL 2.2 +.

Альтернативой безопасности типа является добавление некоторого public enum Type { A, B } вместе с public abstract Type getType() в общий базовый класс модели.

<h:link rendered="#{model.type eq 'A'}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{model.type eq 'B'}">      
    #{errorMessage2}
</h:link>

Любые недопустимые значения приведут к исключению EL во время выполнения в EL 2.2 +.

Ответ 2

Это не работает в EL. Используйте поддержку bean для этого:

public class MyBean {

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


}

И затем выполните проверку, вызвав резервную копию bean:

<h:link outcome="#{PageNameA}?faces-redirect=true&amp;" rendered="#{myBean.isClassA}">      
    #{errorMessage}
</h:link>

Ответ 3

он работает:

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

Ответ 4

Есть способ, см.

JSF EL: экземпляр зарезервирован, но еще не реализован?

Однако оператор instanceof все еще не реализован, по крайней мере, в Mojarra 2.1. Пожалуйста, проголосуйте за ошибку здесь:

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

Лучшим обходным решением в настоящее время является, вероятно, сохранение имени класса в базовом bean getter вместо создания логического метода тестирования для каждого класса:

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

Таким образом, это будет сочетание решений BalusC и flash. Однако в JSF это было бы гораздо более читаемым, чем BalusC plus, оно в значительной степени напоминает будущее использование оператора instanceof:

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

Это не будет производить один метод для каждого теста класса на основе bean, как предлагалось в качестве вспышки. Это может быть медленнее, чем вспышка.

Ответ 5

Определите статическую функцию, например:

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

Определите для него пользовательскую функцию EL и используйте ее. Мы также можем передать имя строки и сделать forName() внутри метода.

Ответ 6

Не очень элегантный, поскольку он смешивает JSP EL и более ранний синтаксис выражений, но не требует дополнительного кода Java:

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

<c:set var="interfaceClass" value="<%=com.example.ClassA.class%>"/>
<c:set var="implementationClass" value="${model['class']}"/>
<c:if test="${interfaceClass.isAssignableFrom(implementationClass)}">
    <%-- Your logic here. --%>
</c:if>