我有一個登錄表單來驗證用戶是否在使用LDAP的活動目錄中。我使用Apache Shiro來做這件事(我相信這不是重要的事情,但我最好提一下,因爲它可能會影響我嘗試工作的內容)。如果用戶輸入錯誤的密碼,則會拋出異常,我希望在我的表單所在的同一頁面上顯示錯誤消息。因此,我按照建議的地方寫了一個自定義異常處理程序,以指定錯誤消息下面是代碼的相關部分:在同一頁面上顯示錯誤消息
的index.xhtml(我的登錄表單):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
>
<h:form>
<h:messages globalOnly="false"/>
<h:panelGrid columns="2">
<h:outputLabel for="username">Username:</h:outputLabel>
<h:inputText id="username" value="#{user.userName}"/>
<h:outputLabel for="password">Password:</h:outputLabel>
<h:inputSecret id="password" value="#{user.password}"/>
<h:message for="username" infoStyle="color:darkgreen" errorStyle="color:red"/>
<h:message for="password" infoStyle="color:darkgreen" errorStyle="color:red"/>
</h:panelGrid>
<h:commandButton value="Login" action="#{loginController.login}" rendered="#{!loginController.loggedIn}"/>
<h:commandButton value="Logout" action="#{loginController.logout}" rendered="#{loginController.loggedIn}"/>
</h:form>
</html>
登錄方法從LoginController中類:
public String login() {
currentUser = ldapUserProvider.provide(); //gets Apache Shiro's Subject which is the user being authenticated.
if (!currentUser.isAuthenticated()) {
CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(DOMAIN, user.getUserName(), user.getPassword());
token.setRememberMe(true);
try {
currentUser.login(token); //this one causes exception if the password is wrong, for example
loggedIn = true;
return "success.xhtml";
} catch (Exception e) {
return "index.xhtml"; //in this case I'd like to show the error message and prompt to login again
}
}
return "index.xhtml";
}
定製的ExceptionHandler:
package com.flyeralarm.tools.apss;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import java.util.Iterator;
public class AuthenticationExceptionHanlder extends ExceptionHandlerWrapper {
private ExceptionHandler wrappedExceptionhandler;
public AuthenticationExceptionHanlder(final ExceptionHandler wrappedExceptionhandler) {
this.wrappedExceptionhandler = wrappedExceptionhandler;
}
@Override
public ExceptionHandler getWrapped() {
return wrappedExceptionhandler;
}
@Override
public void handle() {
Iterator<ExceptionQueuedEvent> eventIterator = getUnhandledExceptionQueuedEvents().iterator();
while (eventIterator.hasNext()) {
ExceptionQueuedEvent event = eventIterator.next();
ExceptionQueuedEventContext eventContext = (ExceptionQueuedEventContext) event.getSource();
Throwable exception = eventContext.getException();
handleException(exception, eventContext);
eventIterator.remove();
getWrapped().handle();
}
}
private void handleException(Throwable exception, ExceptionQueuedEventContext context) {
FacesMessage exceptionMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login failed.", exception.getMessage());
FacesContext facesContext = FacesContext.getCurrentInstance();
Flash flash = facesContext.getExternalContext().getFlash(); //I read that putting the message into flash would do the work but it didn't
flash.put("errorDetails", exception.getMessage());
facesContext.addMessage(null, exceptionMessage);
facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "index?faces-redirect=true");
}
}
我也嘗試過不同的組合,只是全局= true和false,但頁面仍然存在l不顯示我在自定義異常處理程序中定義的錯誤消息。我在做什麼?錯誤?
重複的問題免責聲明:我也搜索了SO網站尋找可能的解決方案,並嘗試了不同答案中提出的事情,但沒有任何幫助。
瞭解「AJAX」 – Kukeltje
我開始在這個題目移動爲好。拉胡爾的解決方案出了什麼問題?發現異常時,您沒有添加任何消息。 – Al1
我會接受拉胡爾的回答,因爲這條線實際上是做這項工作的。我的代碼中的問題是行''''''''''''''''''''''''''''''刪除行顯示錯誤消息。 –