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

Я начинаю с того, для чего можно использовать , и ?

У меня есть прослушиватель события предварительного просмотра:

<f:metadata>
    <f:event type="preRenderView" listener="#{loginBean.performWeakLogin()}" />
</f:metadata>

который вызывает следующий метод:

public String performWeakLogin() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    String parameter_value = (String) facesContext.getExternalContext().getRequestParameterMap().get("txtName");

    if (parameter_value != null && parameter_value.equalsIgnoreCase("pippo")) {
        try {
            return "mainPortal";
        } catch (IOException ex) {
            return null;
        }
    } else {
        return null;
    }
}

и следующее правило навигации:

<navigation-rule>
    <from-view-id>/stdPortal/index.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>mainPortal</from-outcome>
        <to-view-id>/stdPortal/stdPages/mainPortal.xhtml</to-view-id>
        <redirect/>
    </navigation-case>
</navigation-rule>

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

<p:commandButton ... action="#{loginBean.performWeakLogin()}"  /> 

2 ответа

Решение

Навигация на основе возвращаемого значения метода выполняется только компонентами, реализующими ActionSource2 интерфейс и предоставление атрибута, принимающего MethodExpression для этого, таких как action атрибут UICommand компоненты, которые ставятся в очередь на этапе Apply Request Values и вызываются на этапе Invoke Application.

<f:event listener> это просто метод слушателя событий системы компонентов, а не метод действия. Вам необходимо выполнить навигацию вручную следующим образом:

public void performWeakLogin() {
    // ...

    FacesContext fc = FacesContext.getCurrentInstance();
    fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "mainPortal");
}

Кроме того, вы также можете отправить перенаправление на заданный URL-адрес, что более полезно для случая, когда вы не хотите перемещаться внутри, но снаружи:

public void performWeakLogin() throws IOException {
    // ...

    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + "/stdPortal/stdPages/mainPortal.xhtml");
}

Вне зависимости от конкретной проблемы, фильтр сервлетов - лучшее место для выполнения авторизации / аутентификации на основе запросов.

Смотрите также:

Я использую JBoss 7 с JSF 2.1. Решением от BalusC было перенаправление на страницу ошибок JBoss по умолчанию, хотя я уже установил страницу ошибок по умолчанию в web.xml

<error-page>
    <error-code>404</error-code>
    <location>/myapp/404.xhtml</location>
</error-page>

Чтобы перенаправить на свою страницу ошибки, я использовал ответ для отправки ошибки:

FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse)facesContext.getExternalContext().getResponse();
try {
    response.sendError(404);
} catch (IOException ioe) {
    ioe.printStackTrace();
}
facesContext.responseComplete();
Другие вопросы по тегам