在遗留代码库中,我遇到了这个:
@javax.faces.convert.FacesConverter(forClass = java.lang.String.class)
public class WhitespaceToNullConverter implements Converter {
@Override
public Object getAsObject(FacesContext facesContext, UIComponent c, String value) {
if (value == null || value.trim().isEmpty()) {
if (c instanceof EditableValueHolder) {
((EditableValueHolder) c).setSubmittedValue(null);
}
return null;
}
return value;
}
// ...
}
首先,传递的UIComponent
是不是EditableValueHolder
?需要检查吗?
第二,Converter
是否应该更改所要求的UIComponent
?这对我来说似乎很奇怪,假设组件的值可能用于填充UIComponent
。
JavaDoc在这方面没有说什么。
答案 0 :(得分:2)
首先,传递的UIComponent不是EditableValueHolder吗?
通常,只有在JSF需要将提交的值转换为模型值时才会调用getAsObject()
。通常,这仅在UIInput#validate()
中调用。并UIInput
实施EditableValueHolder
。因此,假设正常情况,这个具体问题的答案是“是”。
需要检查吗?
不,但这也不是一个“坏习惯”。它很可能是由一名防御性程序员编写的,他只是想避免在出于某种目的而滥用转换器时出现问题;)
第二,转换器是否应该更改它所要求的UIComponent?
取决于更改的目的。通常确实没有,从用户代码中以编程方式操作JSF组件树是一种不好的做法,但有时候根本就没有其他方法,然后你必须乱搞。
这对我来说似乎很奇怪,假设组件的值可能用于填充UIComponent。
此特定转换器解决了以下相关问题中描述的两个独立问题:
这里唯一奇怪的是第一个问题的setSubmittedValue(null)
解决方案是JSF 1.x特定的,而应用程序显然使用JSF 2.x,正如@FacesConverter
的存在所证明的那样。在之前的JSF 1.x到2.x迁移期间,它很可能被忽略了。在JSF 2.x中,此特定转换器的setSubmittedValue(null)
任务可完全由以下上下文参数替换:
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
这应该让转换器不再看起来像hacky。