根据https://stackoverflow.com/a/8446728/1797006递归使用JSF复合组件nested:cif
并使用c:if
终止递归应该有效:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:nested="http://xmlns.jcp.org/jsf/composite/nested"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<cc:interface>
<cc:attribute name="theAttr"
type="richtercloud.jsf.avoid.nested.rendered.evaluation.Entity0"
required="true"/>
</cc:interface>
<cc:implementation>
<h:outputLabel value="Hello World!"/>
<c:if test="#{cc.attrs.theAttr.reference ne null}">
<nested:cif theAttr="#{cc.attrs.theAttr.reference}"/>
</c:if>
<c:if test="#{cc.attrs.theAttr.reference eq null}">
<h:outputLabel value="recursion terminated"/>
</c:if>
</cc:implementation>
</html>
如下调用:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:nested="http://xmlns.jcp.org/jsf/composite/nested">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<nested:cif theAttr="#{backingBean0.reference}"/>
</h:body>
</html>
支持bean:
@Named
@ViewScoped
public class BackingBean0 implements Serializable {
private Entity0 reference = new Entity0(new Entity0(null));
public Entity0 getReference() {
return reference;
}
public void setReference(Entity0 reference) {
this.reference = reference;
}
}
但是,我得到了
java.lang.StackOverflowError
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.get(HashMap.java:557)
at javax.faces.component.ComponentStateHelper.get(ComponentStateHelper.java:174)
at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2386)
at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
at javax.el.MapELResolver.getValue(MapELResolver.java:199)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.ContextualCompositeValueExpression.getValue(ContextualCompositeValueExpression.java:158)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2427)
at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
at javax.el.MapELResolver.getValue(MapELResolver.java:199)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.ContextualCompositeValueExpression.getValue(ContextualCompositeValueExpression.java:158)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2427)
at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
at javax.el.MapELResolver.getValue(MapELResolver.java:199)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.ContextualCompositeValueExpression.getValue(ContextualCompositeValueExpression.java:158)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2427)
at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
at javax.el.MapELResolver.getValue(MapELResolver.java:199)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
[a few more hundred lines]
当我在Entity0.getReference
中放置调试器断点时,我发现它在StackOverflowError
之前被调用了一次。
Afaik其他SO问题中涉及的唯一其他问题是using rendered
to break the recursion,由于视图构建时间与视图渲染时间不同而无效。
我希望递归会导致&#34; Hello world!&#34;标签要显示两次,因为private Entity0 reference = new Entity0(new Entity0(null));
定义的深度为2(Entity0
是一个只有一个属性的类,它是对自身的引用)然后是&#34;递归终止标签& #34;
可以在https://gitlab.com/krichter/jsf-avoid-nested-rendered-evaluation找到SSCCE。
我在Payara 4.1.2.181上使用Primefaces 6.2。