Как выполнить навигацию в методе прослушивателя 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();