我在facelet上有一個自定義轉換器(對於其他任何對象,只是我的示例中的另一個字符串)以及自定義驗證器( 「需要」的價值,以及其他支票)。這裏有一個用例描述預期的和有問題的實際步驟:如何清除所需的字段值 - 恢復回最後一個有效值
- 輸入一個有效值和模糊字段(標籤輸出或點擊其他元素)。
- 轉換器將字段值更改爲對象的標準化字符串表示形式。 與預期的一樣
- 返回並輸入一個無效值,再次模糊。
- 驗證消息顯示錯誤。 與預期的一樣
- 字段值保持無效值。 與預期的一樣
- 返回並刪除值,再次模糊。
- 驗證消息顯示錯誤。 與預期的一樣
- 字段值變回到最後一個有效(標準化)值。 未如預期,希望它留空
這是一個有點反直覺如果驗證消息顯示值應該提供,而舊的有效值節目。任何想法,即使驗證失敗,我可以做些什麼來保持領域清晰?
我或許需要強調以下關於交換器:
- 空/空字符串轉換爲空對象。 (但驗證器需要一個有效的非空值。)
- 使用
blur
上的ajax調用來在完成鍵入值時始終運行轉換器 - 意圖是將提供的值轉換爲後備對象bean成員,然後轉換回對象的(「規範化」)字符串表示形式。 (「規範化」示例:符合枚舉常數名稱的情況下,或處於某個日期格式。)
我在GlassFish 4.1上使用JSF 2.2(Mojarra 2.2.7)。
示例代碼(修剪回顯到只顯示一個測試用例,但包含的重要組成部分 - 我認爲):
支持bean:
@ManagedBean
@ViewScoped
public class TestBean implements Serializable {
:
private String test; // plus g/setters
:
}
JSF視圖頁面:
<h:form>
:
<h:inputText id="test" binding="#{test}" value="#{testBean.test}">
<cp:uppercaseConverter />
<f:validator binding="${testValidator}" />
<f:ajax event="blur" render="@this msg_test" /><!-- @this forces converter on blur -->
</h:inputText>
<h:messages id="msg_test" for="test" />
:
</h:form>
定製轉換器:(請記住,爲了進行測試有點做作)
/**
* The "object" as used in the backing bean is simply the uppercase version of
* the input value in the field.
*/
@FacesConverter("UppercaseConverter")
public class UppercaseConverter implements Converter, Serializable {
private static final long serialVersionUID = 1L;
@Override
public Object getAsObject(
FacesContext ctx, UIComponent component, String newValue
) throws ConverterException {
if (newValue == null || newValue.trim().equals(""))
return null;
return newValue.toUpperCase();
}
@Override
public String getAsString(
FacesContext ctx, UIComponent component, Object value
) throws ConverterException {
if (value == null) return "";
return value.toString();
}
}
自定義的驗證:(記住,用於測試目的有點做作)
/**
* Values are valid only if they start with an "A" (not case sensitive).
* Thus, null or empty values are also invalid implicitly.
*/
@ManagedBean
@FacesValidator
public class TestValidator implements Validator {
@Override
public void validate(
FacesContext context, UIComponent component, Object value
) throws ValidatorException {
if (value == null || !value.toString().trim().toLowerCase().startsWith("a"))
throw new ValidatorException(new FacesMessage("A value starting with A or a is required"));
}
}