在EL表达式语言instanceof检查(instanceof check in EL expres

2019-06-23 23:19发布

是否有执行方式instanceof在EL检查?

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

Answer 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 2.2+运行期间这里抛出一个异常EL。

如果你正在使用OmniFaces ,因为3.0版,您可以使用#{of:isInstance()}

<h:link rendered="#{of:isInstance('com.example.ClassA', model)}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{of:isInstance('com.example.ClassB', model)}">      
    #{errorMessage2}
</h:link>


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



Answer 3:

有用:

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


Answer 4:

定义一个静态函数,如:

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

定义一个定制的EL功能它,并使用它。 我们也可以通过一个字符串名称和做forName()方法中。



Answer 5:

有一种方法,请参阅

JSF EL:保留的instanceof但尚未实施的?

然而, instanceof运算符仍然没有实现,至少在钻嘴鱼科2.1。 请投票给这里的错误:

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

最好的解决方法目前可能是存储在后台bean的getter类的名称,而不是创建为每个类的布尔测试方法:

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

因此,这将是BalusC的和闪存解决方案的组合。 然而,这将是很大的JSF比BalusC的可读性更强,再加上它非常类似于未来instanceof运算符的使用:

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

这将不会在辅助bean产生每类测试的一种方法,快闪建议。 这可能是比闪存的虽然慢。



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


Answer 7:

你可以使用一个帮手豆:

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

用法:

<h:link rendered="#{helper.isInstance(model, 'package.ClassA')}">
  #{errorMessage1}
</h:link>

这样做的好处是考虑到继承帐户,您可以测试您不能修改(BalusC的解决方案的缺点都)班。

如果你喜欢用简单的类名(不要担心名称冲突),你可以使用你用手或用类似的类路径扫描器填补查找地图org.reflections :

@ManagedBean
@ApplicationScoped
public class Helper {
  private Map<String, Class<? extends MyBaseClass>> classes = 
      new Reflections("myrootpackage").getSubTypesOf(MyBaseClass.class).stream()
      .collect(Collectors.toMap(Class::getSimpleName, Function.identity()));

  public boolean isInstance(Object bean, String simpleClassName) {
    final Class<? extends MyBaseClass> c = this.classes.get(simpleClassName);
    return c != null && c.isInstance(bean);
  }
}

你甚至可以移动辅助函数的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 ...
}

用法:

<h:link rendered="#{model.isInstanceOf('package.ClassA')}">
  #{errorMessage1}
</h:link>


文章来源: instanceof check in EL expression language