是否有执行方式instanceof
在EL检查?
如
<h:link rendered="#{model instanceof ClassA}">
#{errorMessage1}
</h:link>
<h:link rendered="#{model instanceof ClassB}">
#{errorMessage2}
</h:link>
是否有执行方式instanceof
在EL检查?
如
<h:link rendered="#{model instanceof ClassA}">
#{errorMessage1}
</h:link>
<h:link rendered="#{model instanceof ClassB}">
#{errorMessage2}
</h:link>
你可以比较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>
这并不在工作EL
。 使用这个支持bean:
public class MyBean {
public boolean getIsClassA() {
if(model instanceof ClassA) {
return true;
}
return false;
}
}
然后通过调用支持bean做的检查:
<h:link outcome="#{PageNameA}?faces-redirect=true&" rendered="#{myBean.isClassA}">
#{errorMessage}
</h:link>
有用:
rendered="#{node.getClass().getSimpleName() == 'Logt_anno'}"
定义一个静态函数,如:
public boolean isInstanceOf( Object obj, Class targetClass) {
return targetClass.isInstance(obj);
}
定义一个定制的EL功能它,并使用它。 我们也可以通过一个字符串名称和做forName()
方法中。
有一种方法,请参阅
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产生每类测试的一种方法,快闪建议。 这可能是比闪存的虽然慢。
不是很优雅,因为它混合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>
你可以使用一个帮手豆:
@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>