Niestety, taka jest natura tagów <f:xxx>
. Kiedy widok ma zostać zbudowany, budowana jest pojedyncza instancja znacznika, w którym tworzony jest konwerter. Wszystkie jego atrybuty zostały przeczytane i ustawione tylko raz. W chwili, gdy widok został już zbudowany, #{item}
zostaje rozwiązany na null
(jest dostępny tylko podczas renderowania widoku), więc atrybut timeZone
będzie null
, a następnie domyślnie UTC. Gdy widok ma być renderowany, to samo wystąpienie konwertera zostało ponownie użyte dla każdego wiersza tabeli.
Istnieje kilka sposobów rozwiązania tego problemu. Mogę wymyślić niestandardowy konwerter lub funkcję EL. Myślę, że niestandardowy konwerter jest przecież najlepszy, ponieważ może być następnie ponownie użyty w komponentach wejściowych. Poniższy przykład kickoff powinny wypracować dla Ciebie (nullchecks i pominięty dla zwięzłość):
@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);
}
}
który może być używany jako
<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>
ten sposób strefa czasowa jest rozwiązany za każdym konwerter jest wywoływana zamiast podczas jego budowy.
Aktualizacja: the OmniFaces <o:converter>
rozwiązuje dokładnie ten problem bez konieczności niestandardowego konwertera.
<h:outputText value="#{item.time}">
<o:converter converterId="javax.faces.DateTime" pattern="yyyy-MM-dd HH:mm:ssZ" timeZone="#{item.timeZone}" />
</h:outputText>