以下是一种转换器,主要用于修剪前导和尾随空白,并用单个空格替换句子或文本中单词之间的多个空格。现在,将转换器修改为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
像#{empty bean.value ? 'Not available' : bean.value}
在整个应用程序中的任何地方一样,在EL中进行条件测试是不明智的。有什么建议吗?
这是Mojarra 2.2.12。
更新 :
当getFormattedValue()
方法中返回空字符串的return语句之一(为is )被修改为在调用时返回转换后的值""
时,转换后的值可用。currentValue
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);
}
(需要建议)。
首先,Converter
绝对不会强制a为“默认值”。
不论出现什么问题,无论您在做什么getAsString()
,都应确保在将结果传递回时String
可以将结果转换回原始结果。您的转换器不这样做。即使您不太可能使用它,从技术上讲,也需要修改转换器以将确切的字符串转换回。换句话说,你的转换器必须以这样的方式来设计和可顺利通过对方的导致无限循环,并给予同样的结果返回每次。Object
getAsObject()
"Not available"
null
getAsObject()
getAsString()
至于强制使用默认值的具体功能要求,Converter
您应该在模型或视图中执行此操作,而不是在其中进行操作,具体取决于实际默认值来自何处。在您的特定情况下,您只希望在没有此类值的情况下在用户界面中具有默认的占位符文本/标签。这属于视图。
像
#{empty bean.value ? 'Not available' : bean.value}
在整个应用程序中的任何地方一样,在EL中进行条件测试是不明智的。
我完全同意,如果您已经喜欢半途而废的应用程序开发并且在整个地方都有数百个应用程序开发,那么这是一种精神错乱。但是,如果您从一开始就已经考虑到这一点,那就不是疯了。如果没有,那么很好,请学习该课程,咬紧牙关,并定期对代码进行相应的修复。体面的IDE具有基于正则表达式的find&replace,可以帮助实现这一目标。每个人都到过那里,并做了那种精神错乱,甚至是我自己。要减少样板,请将其包装在EL函数或标记文件中。
Converter
关于模型值为时不被调用的具体问题null
,我个人完全同意这是意外行为,这曾被报道为Mojarra问题630。稍后将其以WONTFIX的形式关闭,因为它导致测试用例失败,并且毕竟最好将其报告为JSF规范问题。这样做是作为JSF规范问题475(已经在JSF 1.2中进行的)。我在此检查了MyFaces 2.2.9,它也不会触发转换器,因此暴露了相同的规格问题。
但是,技术问题是可以理解的。一个null
值,没有一个合理的getClass()
,所以变频器不能通过值的类这种方式进行查找。仅当转换器在组件上显式注册时,它才起作用。
<h:outputText value="#{bean.potentiallyNullValue}" converter="stringTrimmer" />
当值是一个空字符串时""
,它应该可以工作,这在getValue()
扩展Mojarra的自定义渲染器中实现起来比较简单TextRenderer
。
@Override
protected Object getValue(UIComponent component) {
Object value = super.getValue(component);
return (value != null) ? value : "";
}
但是,当我在这里尝试尝试时,仍然失败。结果是,当值是的实例时,将完全跳过按类转换器String
。仅当转换器在组件上显式注册时,它仍然有效。这很可能是在实施针对JSF 1.2的规范问题131期间的疏忽(在此版本之前,String.class
根本不支持转换器,并且此问题仅针对解码而不是编码进行了修复)。
可以在同一自定义渲染器(具有上面的getValue()
覆盖)中覆盖此对象,并在下面的覆盖中getFormattedValue()
显式查找转换器。
@Override
protected String getFormattedValue(FacesContext context, UIComponent component, Object currentValue) throws ConverterException {
Converter converter = ((UIOutput) component).getConverter();
if (converter == null) {
converter = context.getApplication().createConverter(currentValue.getClass());
}
return super.getFormattedValue(context, component, "".equals(currentValue) ? null : currentValue, converter);
}
请注意,您不需要检查,UIInput
因为您仅在javax.faces.Output
/javax.faces.Text
组件系列/类型上显式注册了自定义渲染器(即,它仅在<h:outputText>
组件上运行)。
尽管如此,最好的解决方案仍然是为此创建一个EL函数或标记文件。
<h:outputText value="#{empty bean.value ? 'Not available' : bean.value}" />
<h:outputText value="#{of:coalesce(bean.value, 'Not Available')}" />
<h:outputText value="#{of:coalesce(bean.value, i18n.na)}" />
<h:outputText value="#{your:value(bean.value)}" />
<your:text value="#{bean.value}" />
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句