Перезаписать JSF viewParam с обратной передачей, затем перенаправить на себя - PullRequest
0 голосов
/ 26 февраля 2012

У меня есть страница JSF 2.0, для которой я хочу разрешить ввод параметра GET и установить значение бина.Кроме того, я хочу разрешить изменение этого бина из формы на той же странице, а затем перенаправить обратно на ту же страницу с новым параметром GET.Как вы, вероятно, ожидаете, я хочу, чтобы эта страница могла быть добавлена ​​в закладки.

Однако у меня возникают проблемы, когда исходный запрос GET содержит недопустимый (не проходит проверку) параметр для повторной проверки компонента.Сначала проблема не была очевидна для меня, но после проверки журнала стало совершенно очевидно, что происходит.Когда commandButton проверяет действительность только что введенного значения, JSF проверяет исходный параметр GET, а также вновь введенное значение.Поскольку параметр GET не прошел проверку в первую очередь, он снова не проходит.К сожалению, это препятствует тому, чтобы новое значение заняло его место.

Даже когда значения GET действительны, они все еще проверяются снова, что является пустой тратой времени, перед проверкой новых значений.Есть ли способ в основном отбрасывать параметры GET после их загрузки, независимо от того, проходят ли они проверку, или нет, так что проверяются только текущие значения?

Подробности:

Я включаюФорма поиска на главной странице, и она выполняет проверку Ajax (стандартная проверка bean-компонентов с использованием h:inputText и p:commandButton (Primefaces), но это также не происходит, когда я использую h:commandButton), чтобы гарантировать, что пользователь отправляет данные (не пустые),После успешной проверки страница перенаправляется с помощью действия:

listing?faces-redirect=true&includeViewParams=true

Форма:

<h:form id="search">
    <p:messages id="qError" />
    <h:inputText value="#{pageSearchBean.search}" id="q"
                 validator="#{pageSearchBean.validateSearchNotBlank}" />
    <p:commandButton value="Find" action="#{pageSearchBean.searchAction}"
                     update="qError" />
</h:form>

(Примечание. Проблема по-прежнему возникает, даже если я удаляю validator изh:inputText пока я оставляю это на viewParam)

Эта часть работает отлично.В случае успеха страница перенаправляется на listing.jsf?q=xyz, как и ожидалось, и вставляет переданное значение (в pageSearchBean, затем выполняет поиск на основе события preRenderView. Если я введу недопустимое значение на домашней странице, токнопка правильно информирует меня о том, что данные были недействительными, после их исправления корректно перенаправляется на listing.jsf?q=whatever+I+typed.

Перевод параметра GET в bean-компонент:

<f:metadata>
    <f:viewParam name="q" value="#{pageSearchBean.search}"
                 validator="#{pageSearchBean.validateSearchNotBlank}" />
    <f:event type="preRenderView" listener="#{pageSearchBean.doSearch}" />
</f:metadata>

Теперь нана странице листинга я повторно использую точную ту же форму поиска / Facelet, импортируя тот же Facelet, но я также показываю результаты для фактического поиска, аналогичные почти всем поисковым страницам, которые вы когда-либо использовали.

Как есть, страница всегда выполняет двойную проверку

public class PageSearchBean implements Serializable
{
    protected static final Log LOGGER =
            LogFactory.getLog(PageSearchBean.class);

    protected final List<Page> results = new ArrayList<Page>();
    protected String search = "";

    public String getSearch()
    {
        // all logging just to watch how things are requested
        LOGGER.fatal(String.format("getSearch() = '%s'", search));

        return search;
    }

    public void setSearch(String search)
    {
        LOGGER.fatal(String.format("setSearch('%s')", search));

        this.search = search;
    }

    public List<Page> getResults()
    {
        return results;
    }

    public void doSearch()
    {
        LOGGER.fatal(String.format("doSearch() for '%s'", getSearch()));

        // generate random data/search results (if we haven't already
        //  and we have search terms)
    }

    public String searchAction()
    {
        LOGGER.fatal("searchAction()");

        return "listing?faces-redirect=true&amp;includeViewParams=true";
    }

    public void validateSearchNotBlank(FacesContext context,
                                       UIComponent validate,
                                       Object value)
            throws ValidatorException
    {
        LOGGER.fatal(String.format("validate('%s')", value));

        // throws new ValidatorException when blank (null or all whitespace)
    }
}

1 Ответ

1 голос
/ 26 февраля 2012

Одно непривлекательное решение состоит в том, чтобы избежать проверки параметров GET на уровне JSF и просто проверить значения на уровне установщика (игнорировать недопустимые данные).

Поскольку я готов принять неустановленные параметры дляМой вариант использования, это хороший обходной путь здесь.Тем не менее, я надеюсь на более полезное решение, которое позволит мне избежать загромождения установщика валидацией, поскольку страница JSF не может дважды проверять валидацию.

...