Доброе утречко!
Сегодня рассмотрим такую задачу, как выбор null
значения в компоненте p:SelectOneMenu
Что у нас имеется:
Форма с selectOneMenu
<p:selectOneMenu id="parent-unit-selector" value="#{unitBean.selectedParentUnit}"
converter="#{unitConverter}">
<f:selectItem itemLabel="-" itemValue=""/>
<f:selectItems value="#{unitBean.parents}" var="p"
itemLabel="#{p.name}"
itemValue="#{p}"/>
</p:selectOneMenu>
Конвертер:
@FacesConverter("unitConverter")
@ManagedBean(name = "unitConverter")
@ApplicationScoped
public class UnitConverter implements Converter {
@ManagedProperty(value = "#{unitUtil}")
@Getter
@Setter
private UnitUtill unitUtill;
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if (value != null && value.trim().length() > 0) {
try {
return unitUtil.getUnit(Long.parseLong(value));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid unit."));
}
} else {
return null;
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if (object != null) {
return String.valueOf(((Unit) object).getId());
} else {
return null;
}
}
}
Ну и бин, код которого, в общем то, ни на что не влияет.
В Primefaces 6.2 данная комбиная f:selectItem с itemalue="" и конвертера работает прекрасно, однако в версии 7.0 мы получаем такую ошибку при рендере страницы.
class java.lang.String cannot be cast to class com.tuneit.Unit
Заменим значение itemValue
с ""
на "#{null}"
. Проблемма с класс-кастом пропала, однако теперь в конвертер приходит значение не itemValue
, а itemLabel
.
Это происходит потому, что наш конвертер null
значение в методе getAsString
преобразовывает к null, в результате чего JSF не рендерит аттрибут value
у тега option
и браузер при выборе значения отправляет на сервер значение лейбла. Дабы этого избежать немножко подправим наш конвертер, чтобы вместо null он возвращал пустую строку.
@FacesConverter("unitConverter")
@ManagedBean(name = "unitConverter")
@ApplicationScoped
public class UnitConverter implements Converter {
@ManagedProperty(value = "#{unitUtil}")
@Getter
@Setter
private UnitUtill unitUtill;
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if (value != null && value.trim().length() > 0) {
try {
return unitUtil.getUnit(Long.parseLong(value));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid unit."));
}
} else {
return null;
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if (object != null) {
return String.valueOf(((Unit) object).getId());
} else {
return "";
}
}
}
После данных нехитрых манипуляций, наш компонент заработает как и ожидается.