JSF 2 - проверка и перенаправление параметров просмотра - PullRequest
2 голосов
/ 02 июня 2011

Мы используем JSF 2 + Primefaces + Glassfish + CDI / WELD для разработки. На нашей странице search.xhtml есть таблица данных / dataTable списков книг, каждый из которых отображается как outputLink. При нажатии на любую запись отображается view.xhtml со всеми подробностями книги. Это код в нашем search.xhtml, который вызывается:

<h:outputLink value="${request.contextPath}/viewBook.xhtml?id=${book.id}">${book.title} 
</h:outputLink> 

В файле viewBook.xhtml, основанном на идентификаторе книги, переданном в URL, детали заполняются перед отображением страницы следующим образом:

<f:metadata>
    <f:viewParam name="id" value="#{bookBean.id}"/>     
        </f:viewParam>
    <f:event type="preRenderView" listener="#{bookBean.populate}" />
</f:metadata>

Наше требование состоит в том, чтобы проверить Id перед рендерингом страницы, и если его нет в нашей БД, нам нужно перенаправить его на страницу ошибки или показать сообщение об ошибке на той же странице, то есть на странице поиска

Мы пытались проверить Идентификатор книги двумя различными способами: 1. Использование проверки в методе заполнения следующим образом

if (bookFound)
{
    //Display details
}
else
{
    FacesContext fc = FacesContext.getCurrentInstance();
    fc.addMessage("id", new FacesMessage("No such book found in the system. Please try again."));
    fc.renderResponse();
}
  1. Подключив пользовательский валидатор в view.xhtml и выбрав исключение валидатора (сообщение Faces) на экране. Мы используем CDI-WELD, поэтому мы можем использовать инъекцию.

    <f:metadata>
        <f:viewParam name="id" value="#{bookBean.id}"/>
       <f:validator validatorId="bookIdValidator"/>
        </f:viewParam>
        <f:event type="preRenderView" listener="#{bookBean.populate}" />
    </f:metadata>
    

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

FacesContext.getCurrentInstance().getExternalContext().redirect("/error.xhtml");
  1. Есть ли способ обработать проверку таким образом, чтобы сообщения об ошибках отображались на странице поиска, где нажимается outputLink. Мы понимаем, что нам нужно обрабатывать проверку на странице поиска, но как можно связать валидатор с h: outputLink. Можем ли мы использовать h: link в качестве альтернативы (нам нужно использовать GET-запросы, а не POST .. поэтому использование commmandLink или Button невозможно)
  2. Есть ли лучший способ перенаправить на страницу с ошибкой, чем то, как мы это делаем.

    (FacesContext.getCurrentInstance () getExternalContext () перенаправления ( "/ error.xhtml");..) * 1 031 *

Любые указатели будут с благодарностью.

Спасибо и всего наилучшего

Ответы [ 2 ]

1 голос
/ 03 июня 2011

gkari,

Можете ли вы использовать JSF для навигации? Я не знаком с WELD, но решение на чистом JSF может работать следующим образом. Это предполагает, что у вас есть резервный компонент с именем bookBean. У него должно быть свойство с именем id, с геттером (getId) и сеттером (setId).

  1. Создайте пустой метод в вашем компоненте поддержки. Он не должен принимать никаких параметров и возвращать строку.

    String viewBook() {
        // We'll fill this in later.
        return "success";
    }
    
  2. Измените h:outputLink на h:commandLink, что вызывает новый метод:

    <h:commandLink action="#{bookBean.viewBook}" />
    
  3. Обновите ссылку, установив свойство bookBean id при активации ссылки:

    <h:commandLink action="#{bookBean.viewBook}">
        <f:setPropertyActionListener
            target="#{bookBean.id}"
            value="#{book.id}" />
    </h:commandLink>
    
  4. Обновите новый метод в вашем компоненте поддержки, чтобы выполнить необходимую проверку, и верните строку, указывающую успех или неудачу:

    String viewBook() {
        String result;
    
        if (bookIdIsValid (this.getId()) {
            result = "success";
        } else {
            result = "error";
        }
    
        return result;
    }
    
  5. Создайте правила навигации в вашем face-config.xml для маршрутизации к правильной цели в зависимости от кода результата:

    <navigation-rule>
        <from-view-id>/search.xhtml</from-view-id>
        <navigation-case>
            <from-action>#{bookBean.viewBook}</from-action>
            <from-outcome>success</from-outcome>
            <to-view-id>/viewBook.xhtml</to-view-id>
        </navigation-case>
        <navigation-case>
            <from-action>#{bookBean.viewBook}</from-action>
            <from-outcome>error</from-outcome>
            <to-view-id>/error.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
    

Это позволяет компоненту поддержки указать результат в JSF, а библиотека JSF будет обрабатывать перенаправление в соответствующее местоположение.

0 голосов
/ 08 июня 2011

Похоже, проблема в том, что вы создаете сообщение FacesMessage на одной странице, но хотите, чтобы оно отображалось на другой странице. Вам нужно будет втиснуть FacesMessage в сеанс пользователя (или, возможно, в более короткую жизненную область, если он доступен), а затем вытащить его на страницу, на которой вы хотите его отобразить.

Есть несколько попыток автоматизировать это:

В JSF 2 есть область действия Flash и метод setKeepMessages. Вы можете попробовать это, но мне не очень повезло с этим.

Здесь обсуждается решение для прослушивания фазы копирования и вставки: http://ocpsoft.com/java/persist-and-pass-facesmessages-over-page-redirects/

Отображение сообщений через перенаправления также является функцией Seam 3.

...