Ответ 1
К сожалению, это характер тегов <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>