Ниже представлен конвертер, в основном предназначенный для обрезания пробелов в верхнем и заднем пробелах и замены более одного пробела между словами в предложении или тексте с одним пространством. Преобразователь теперь модифицируется для замены null или пустых строк с помощью "Недоступно" (при необходимости может быть локализовано динамически).
@FacesConverter(forClass = String.class)
public class StringTrimmer implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return Boolean.TRUE.equals(component.getAttributes().get("skipConverter")) ? value : value == null ? null : value.trim().replaceAll("\\s+", " ");
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return Boolean.TRUE.equals(component.getAttributes().get("skipConverter")) ? value == null ? null : value.toString() : value == null || ((String) value).trim().length() == 0 ? "Not available" : ((String) value).trim().replaceAll("\\s+", " ");
}
}
Поскольку преобразователи не вызывают, когда значение модели null на основе предыдущего вопроса, com.sun.faces.renderkit.html_basic.TextRenderer было расширено с целью вызова конвертеров, когда значение свойства в связанной модели равно null.
public final class HtmlBasicRenderer extends TextRenderer {
@Override
public String getCurrentValue(FacesContext context, UIComponent component) {
if (component instanceof UIInput) {
Object submittedValue = ((UIInput) component).getSubmittedValue();
if (submittedValue != null) {
return submittedValue.toString();
}
}
return getFormattedValue(context, component, getValue(component));
}
}
следующий условный тест был удален, поэтому метод getFormattedValue() может быть вызван, даже если встречается значение null.
Object currentObj = getValue(component);
if (currentObj != null) {
currentValue = getFormattedValue(context, component, currentObj);
}
Это зарегистрировано в faces-config.xml следующим образом.
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.Text</renderer-type>
<renderer-class>com.example.renderer.HtmlBasicRenderer</renderer-class>
</renderer>
</render-kit>
Преобразователь StringTrimmer все еще не вызывается (getAsString()), когда значение свойства в целевой модели возвращает null.
Включение условного теста в EL, как #{empty bean.value ? 'Not available' : bean.value} повсюду в приложении, является безумием. Любое предложение?
Это Mojarra 2.2.12.
Обновление:
Конвертируемые значения доступны, когда один из операторов return внутри метода getFormattedValue() возвращает пустую строку "", когда currentValue is null, изменяется для возврата преобразованного значения при вызове
javax.faces.convert.Converter.getAsString(FacesContext context, UIComponent component, Object value)
внутри этого метода getFormattedValue().
Таким образом, после,
if(currentValue == null) {
return "";
}
необходимо заменить на
if (currentValue == null) {
converter = Util.getConverterForClass("".getClass(), context);
return converter == null ? "" : converter.getAsString(context, component, currentValue);
}
(Требует предложений).