我想知道为什么我会在下面找到NullPointerException
:
<h:dataTable value="#{testBean.entities}" var="d">
<h:column p:data-order="#{d.modifiedOn}">
<f:facet name="header">Date</f:facet>
<h:outputText value="#{d.modifiedOn}">
<f:convertDateTime pattern="#{msg.datePattern}" />
</h:outputText>
</h:column>
</h:dataTable>
p
命名空间为xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
,modifiedOn
为(非空)Date
字段。
例外情况如下:
Caused by: java.lang.NullPointerException
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.getAttributeValue(HtmlResponseWriter.java:1211)
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.flushAttributes(HtmlResponseWriter.java:1171)
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.closeStartIfNecessary(HtmlResponseWriter.java:1113)
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.writeText(HtmlResponseWriter.java:936)
at com.sun.faces.facelets.el.ELText$ELTextVariable.writeText(ELText.java:240)
at com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:85)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
at com.sun.faces.renderkit.html_basic.TableRenderer.renderHeader(TableRenderer.java:339)
但是,在#{d.modifiedOn}
之类的任何非直通属性中使用headerClass
都可以。与任何未在passthrough属性中引用迭代变量的值一样。
我的问题是:这是打算吗?
这是使用Wildfly-8.0.0.Final的JSF实现,版本2.2.5-jbossorg-3。
如果有人想知道:我正在尝试支持datatables正交数据属性来增强我的表格。
编辑添加:我也尝试过,但是在<h:column>
添加以下内容时遇到了相同的异常:
<f:passThroughAttribute name="data-order" value="#{d.modifiedOn}" />
这显然是由于JSF试图在rowIndex
为-1
并且迭代数据尚未出现的标题上呈现此属性而引起的。所以对我的具体问题有一个黑客解决方案:
<h:column p:data-order="#{empty d or empty d.modifiedOn ? '' : d.modifiedOn.time}">
...
</h:column>
仍会在我的data-order
中呈现空/无用的thead
属性。
进一步测试:
更多的测试证实了我的怀疑,这只发生在任何列上的<f:facet name="header">
(不必是具有该属性的列)。抛弃那些使我失败的目标是使用表作为数据表的基础,因为这需要一个格式良好的表<thead>
。
答案 0 :(得分:1)
这是打算吗? Definitelly不是。此外,这里是根据JSF 2.2规范定义的passthrough属性:
传递属性
对于视图中的任何给定JSF组件标记,组件支持的可用属性集由a确定 该标记的UIComponent和Renderer的组合。在某些情况下,属性的值由解释 UIComponentor Renderer(例如,h:panelGrid的columns属性)和其他值的值 直接传递给用户代理(例如,h:inputText的lang属性)。
在这两种情况下, UIComponent / Renderer具有允许属性集的先验知识。通过属性允许 视图作者列出直接传递给用户代理而没有解释的任意名称值对 由UIComponent / Renderer提供。在“渲染通过属性”中规范地指定了此行为 标准HTML_BASIC渲染工具包概述部分。
因此,这种属性的唯一功能是通知渲染器它必须处理属性的值,但它不依赖于任何UIComponent功能,因此必须以最终输出结束强>
我已经使用Tomcat 7 + Mojarra 2.2.6进行了测试,它对我来说非常适合。 HTML 元素使用其给定日期的数据顺序属性在DOM树中呈现。这是我用过的测试案例:
<html xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://xmlns.jcp.org/jsf/passthrough">
<h:head />
<h:body>
<h:dataTable value="#{bean.entities}" var="entity">
<h:column p:data-order="#{entity.modifiedOn}">
#{entity.name}
</h:column>
</h:dataTable>
<h:messages />
</h:body>
</html>
@ManagedBean
@ViewScoped
public class Bean {
public class Entity {
private String name;
private Date modifiedOn;
public Entity(String name, Date modifiedOn) {
this.name = name;
this.modifiedOn = modifiedOn;
}
public Date getModifiedOn() {
return modifiedOn;
}
public String getName() {
return name;
}
}
/**
* Create a List of entities with dates differing from now to now + 2 days
*/
public List<Entity> entities = Arrays.asList(
new Entity("name1", new Date()), new Entity("name2", new Date(
new Date().getTime() + (1000 * 60 * 60 * 24))), new Entity(
"name0", new Date(new Date().getTime()
+ (1000 * 60 * 60 * 48))));
public List<Entity> getEntities() {
return entities;
}
}
这意味着它是您的JSF实现中的一个错误(我不了解BTW的实现)。除非作者已经在以后的版本中修复过它,否则你最好打开一个bug轨道。
修改强>
当数据表涉及页眉或页脚f:facet
时,渲染失败并显示给定错误。显然,Mojarra尝试在构建迭代器之前评估facet的passthrough值,这会导致它失败,因为变量尚不可用。打开issue。
另见: