不幸的是,這就是<f:xxx>
標籤的性質。在構建視圖時,在轉換器實例化的地方構建了一個標籤實例。所有的屬性都被讀取和設置一次。在構建視圖時,#{item}
解析爲null
(它僅在呈現視圖期間可用),因此timeZone
屬性將爲null
,然後默認爲UTC。當視圖被渲染時,表格的每一行都重複使用了相同的轉換器實例。
有幾種方法可以解決這個問題。我可以考慮一個自定義轉換器或EL功能。我認爲自定義轉換器畢竟是最好的,因爲它也可以在輸入組件中重用。下面開球例子應該制定出適合你(nullchecks並不再贅述):
@FacesConverter("extendedDateTimeConverter")
public class ExtendedDateTimeConverter extends DateTimeConverter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
setPattern((String) component.getAttributes().get("pattern"));
setTimeZone(TimeZone.getTimeZone((String) component.getAttributes().get("timeZone")));
return super.getAsObject(context, component, value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
setPattern((String) component.getAttributes().get("pattern"));
setTimeZone(TimeZone.getTimeZone((String) component.getAttributes().get("timeZone")));
return super.getAsString(context, component, value);
}
}
可以用來作爲
<h:outputText value="#{item.time}">
<f:converter converterId="extendedDateTimeConverter" />
<f:attribute name="pattern" value="yyyy-MM-dd HH:mm:ssZ" />
<f:attribute name="timeZone" value="#{item.timeZone}" />
</h:outputText>
這樣的時區是每次解決了轉換器被調用,而不是在它的建設期間。
更新:在OmniFaces <o:converter>
正好解決了這個問題,而無需自定義轉換器。
<h:outputText value="#{item.time}">
<o:converter converterId="javax.faces.DateTime" pattern="yyyy-MM-dd HH:mm:ssZ" timeZone="#{item.timeZone}" />
</h:outputText>