Проверка страницы JSF в Java и проблема с сгенерированными идентификаторами компонентов

У меня есть вопрос по объекту <h:message for="" /> JSF. У меня есть проект JSF 1.1 (да, к сожалению) myFaces. Я подготовил простой файл JSP с меткой, inputText и держателем сообщения:

<h:form id="sacLinkForm">
    <cblFaces:outputLabel for="dedicatedCashAccountNumber"
        value="#{appBundle.KUSTA_DEDICATED_CASH_ACCOUNT_NUMBER}"/>
    <t:inputText id="dedicatedCashAccountNumber"
        value="#{createController.modelFE.sacLink.dedicatedCashAccountNumber}"/>
    <h:message id="dedicatedCashAccountNumberError"
        for="dedicatedCashAccountNumber" />
</h:form>

Также я создал простой метод проверки:

public static boolean validate(SACLink link) {
    boolean isError = false;
    FacesContext context = FacesContext.getCurrentInstance();
    FacesMessage message = new FacesMessage();
    message.setSeverity(FacesMessage.SEVERITY_ERROR);

    if (StringUtils.isEmpty(link.dedicatedCashAccountNumber)) {
        //MessageUtils.addErrorMessage("dedicatedCashAccountNumber", "Dedicated Cash Account Number is mandatory");
        message.setSummary("Field mandatory");
        message.setDetail("Dedicated Cash Account Number is mandatory");
        context.addMessage("sacLinkForm:dedicatedCashAccountNumber", message);
        isError = true;
    }
    return !isError;
}

Моя проблема связана с sacLinkForm:dedicatedCashAccountNumber, потому что скомпилированный JSP сгенерировал идентификатор (например, _idJsp12:DynTab2:DynView2:tabK.....er:vKustaMa....Controller:sacLinkForm:dedicatedCashAccountNumber), и это, вероятно, приводит к тому, что метод addMessage не соответствует атрибуту h:message for="..".

Таким образом, сообщение отображается неправильно, потому что java не может найти правильный объект h:message. Есть ли способ установить правильное сообщение h:message из Java? Я предполагаю, что нет способа принудительно установить «постоянный» идентификатор компонента на страницах JSF 1.1.

Спасибо.


person Jiri Vlasimsky    schedule 13.03.2013    source источник
comment
Вы пытались добавить prependId=false в форму? и используйте выделенныйCashAccountNumber вместо sacLinkForm:dedicatedCashAccountNumber   -  person Laabidi Raissi    schedule 13.03.2013
comment
@Laabidi: prependId был представлен в JSF 1.2. ОП использует JSF 1.1.   -  person BalusC    schedule 13.03.2013
comment
А, извините, подтверждаю. Я просто проверял это (после сомнения). Даже prependId не был доступен в JSF 1.1.   -  person Laabidi Raissi    schedule 13.03.2013
comment
как написал @BalusC. prependId и другие модификаторы идентификаторов были добавлены в следующих выпусках JSF. :/   -  person Jiri Vlasimsky    schedule 14.03.2013


Ответы (1)


Вы вообще не должны вручную выполнять проверку в методе действия JSF. Вы должны использовать встроенные средства проверки JSF. Вы должны использовать обычный JSF Validator. Любой ValidatorException, который вы выбрасываете оттуда, окажется в правильном компоненте сообщения.

Замените этот метод validate() следующим классом:

public class AccountNumberValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        if (StringUtils.isEmpty(value)) {
            FacesMessage message = new FacesMessage();
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            message.setSummary("Field mandatory");
            message.setDetail("Dedicated Cash Account Number is mandatory");
            throw new ValidatorException(message);
        }
    }

}

Зарегистрируйте его в faces-config.xml следующим образом:

<validator>
     <validator-id>accountNumberValidator</validator-id>
     <validator-class>com.example.AccountNumberValidator</validator-class>
</validator>

Используйте его в представлении следующим образом:

<t:inputText id="dedicatedCashAccountNumber"
    value="#{createController.modelFE.sacLink.dedicatedCashAccountNumber}"
    validator="accountNumberValidator" />

Вот и все. Обратите внимание, что метод действия JSF не будет вызываться, если проверка (или преобразование) не удалась. Нет необходимости в бессмысленном isError беспорядке.

person BalusC    schedule 13.03.2013
comment
Спасибо за ваш ответ. Я также рассматривал возможность использования отдельного валидатора для каждого правила. Но я не хочу создавать новый валидатор для каждого нового правила проверки. Но вы правы, это определенно рабочее и чистое решение. Но я немного боюсь некоторых более сложных правил проверки, таких как f.e. зависимые поля формы (например, startDate › endDate; флажок == установлен, тогда другое поле будет проверяться по-другому). Но я могу в большинстве случаев проверить их после в контроллере с возвратом сообщения об ошибке на вкладку сводки ошибок (не в поле h: message) и заблокировать дальнейший прогресс. - person Jiri Vlasimsky; 14.03.2013
comment
Проверка нескольких полей объясняется в stackoverflow.com/questions/6282466/ Если вы используете JSF2 или понимаете исходный код JSF2, у OmniFaces есть несколько решений с открытым исходным кодом, см. раздел валидаторов в нижней части левого меню: showcase.omnifaces.org - person BalusC; 14.03.2013