javax.faces.convert.Converter.getAsObject应该修改传递的UIComponent吗?

时间:2016-11-15 23:15:41

标签: jsf converter

在遗留代码库中,我遇到了这个:

@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在这方面没有说什么。

1 个答案:

答案 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。

另见: