2011-04-13 29 views
0

我有一個由JSF頁面+託管bean + EJB組成的登錄機制,但它的工作正常,但唯一的錯誤是,當我看不到錯誤消息密碼輸入錯誤。有任何想法嗎?當密碼錯誤時,登錄表單不顯示驗證消息

當輸入密碼錯誤,這是我所得到的在瀏覽器中:

enter image description here

我能避免這種情況,如果我不扔在catch一個ValidationException在EJB(見EJB代碼下面),但是當密碼輸入錯誤時,我根本沒有看到任何驗證消息。

這是在頁面代碼的形式:

<h:form> 
    <p:panel>     
       <h:outputText value="*[email protected]:" /> 
       <h:inputText id="email" value="#{securityController.email}" binding="#{emailComponent}"/>     
       <br/> 
       <h:outputText value="*Lozinka: " /> 
       <h:inputSecret id="password" value="#{securityController.password}" validator="#{securityController.validate}">      
        <f:attribute name="emailComponent" value="#{emailComponent}" /> 
       </h:inputSecret>    

       <br/> 
       <span style="color: red;"><h:message for="password" 
       showDetail="true" /></span> 
       <br/> 
       <h:commandButton value="Login" action="#{securityController.logIn()}"/>     

      </p:panel> 
     </h:form> 

這是managedBean代碼:

@ManagedBean 
@RequestScoped 
public class SecurityController { 

    @EJB 
    private IAuthentificationEJB authentificationEJB; 
    private String email; 
    private String password; 
    private String notificationValue; 

    public String logIn() { 
     if (authentificationEJB.saveUserState(email, password)) { 
      notificationValue = "Dobro dosli"; 
      return "main.xhtml"; 
     } else { 
      return ""; 
     } 

    } 

    public void validate(FacesContext context, UIComponent component, 
      Object value) throws ValidatorException { 

     UIInput emailComponent = (UIInput) component.getAttributes().get(
       "emailComponent"); 
     String email = ""; 
     String password = ""; 
     email = (String) emailComponent.getValue(); 
     password = (String) value; 

     String emailInput = email; 
     String emailPatternText = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; 
     Pattern emailPattern = null; 
     Matcher emailMatcher = null; 
     emailPattern = Pattern.compile(emailPatternText); 
     emailMatcher = emailPattern.matcher(emailInput); 

     String passwordInput = password; 
     String alphanumericPattern = "^[a-zA-Z0-9]+$"; 
     Pattern passwordPattern = null; 
     Matcher passwordMatcher = null; 
     passwordPattern = Pattern.compile(alphanumericPattern); 
     passwordMatcher = passwordPattern.matcher(passwordInput); 

     if (!emailMatcher.matches() && !passwordMatcher.matches()) { 
      if (authentificationEJB.checkCredentials(emailInput, passwordInput) == false) { 
       FacesMessage msg = new FacesMessage(
         "Pogresan email ili lozinka"); 
       throw new ValidatorException(msg); 
      } 
     } 
     if(emailInput == null || passwordInput == null) { 
      FacesMessage msg = new FacesMessage("Pogresan email ili lozinka"); 
      throw new ValidatorException(msg); 
     } 
     if (passwordInput.length() <= 0 || emailInput.length() <= 0) { 
      FacesMessage msg = new FacesMessage("Pogresan email ili lozinka"); 
      throw new ValidatorException(msg); 
     } 
    } 

    public String getEmail() { 
     return email; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public String getNotificationValue() { 
     return notificationValue; 
    } 

    public void setNotificationValue(String notificationValue) { 
     this.notificationValue = notificationValue; 
    } 
} 

這是EJB

@Stateful(name = "ejbs/AuthentificationEJB") 
public class AuthentificationEJB implements IAuthentificationEJB { 

    @PersistenceContext 
    private EntityManager em; 

    // Login 
    public boolean saveUserState(String email, String password) { 
     // 1-Send query to database to see if that user exist 
     Query query = em 
       .createQuery("SELECT r FROM Role r WHERE r.email=:emailparam AND r.password=:passwordparam"); 
     query.setParameter("emailparam", email); 
     query.setParameter("passwordparam", password); 
     // 2-If the query returns the user(Role) object, store it somewhere in 
     // the session 
     try { 
      Role role = (Role) query.getSingleResult(); 
      if (role != null && role.getEmail().equals(email) 
        && role.getPassword().equals(password)) { 
       FacesContext.getCurrentInstance().getExternalContext() 
         .getSessionMap().put("userRole", role); 
       // 3-return true if the user state was saved 
       System.out.println(role.getEmail() + role.getPassword()); 
       return true; 
      } 
     } catch (Exception e) { 
          FacesMessage msg = new FacesMessage("Pogresan email ili lozinka"); 
      throw new ValidatorException(msg); 
     } 
     // 4-return false otherwise 
     return false; 
    } 

    // Logout 
    public void releaseUserState() { 
     // 1-Check if there is something saved in the session(or wherever the 
     // state is saved) 
     if (!FacesContext.getCurrentInstance().getExternalContext() 
       .getSessionMap().isEmpty()) { 
      FacesContext.getCurrentInstance().release(); 
     } 
     // 2-If 1 then flush it 
    } 

    // Check if user is logged in 
    public boolean checkAuthentificationStatus() { 
     // 1-Check if there is something saved in the session(This means the 
     // user is logged in) 
     if ((FacesContext.getCurrentInstance().getExternalContext() 
       .getSessionMap().get("userRole") != null)) { 
      // 2-If there is not a user already loged, then return false 
      return true; 
     } 

     return false; 
    } 

    @Override 
    public boolean checkCredentials(String email, String password) { 
     Query checkEmailExists = em 
       .createQuery("SELECT COUNT(r.email) FROM Role r WHERE r.email=:emailparam AND r.password=:passwordparam"); 
     checkEmailExists.setParameter("emailparam", email); 
     checkEmailExists.setParameter("passwordparam", password); 
     long matchCounter = 0; 
     matchCounter = (Long) checkEmailExists.getSingleResult(); 
     if (matchCounter > 0) { 
      return true; 
     } 
     return false; 
    } 
} 
代碼

這裏在EJB中,我認爲我犯了一個錯誤,如果我在catch塊中拋出ValidationException,因爲我認爲顯示err或者前端的消息應該是託管bean的任務。我不明白爲什麼表單不顯示錯誤,因爲當密碼錯誤時字段爲空(當電子郵件錯誤時,它會正確顯示驗證消息)。

更新

改變了saveUserState()方法在EJB到:

// Login 
public boolean saveUserState(String email, String password) { 
    // 1-Send query to database to see if that user exist 
    Query query = em 
      .createQuery("SELECT r FROM Role r WHERE r.email=:emailparam AND r.password=:passwordparam"); 
    query.setParameter("emailparam", email); 
    query.setParameter("passwordparam", password); 
    // 2-If the query returns the user(Role) object, store it somewhere in 
    // the session 
    List<Object> tmpList = query.getResultList(); 
    if (tmpList.isEmpty() == false) { 
     Role role = (Role) tmpList.get(0); 
     if (role != null && role.getEmail().equals(email) 
       && role.getPassword().equals(password)) { 
      FacesContext.getCurrentInstance().getExternalContext() 
        .getSessionMap().put("userRole", role); 
      // 3-return true if the user state was saved 
      System.out.println(role.getEmail() + role.getPassword()); 
      return true; 
     } 
    } 
    // 4-return false otherwise 
    return false; 
} 

支票憑證方法:

public boolean checkCredentials(String email, String password) { 
    Query checkEmailExists = em 
      .createQuery("SELECT COUNT(r) FROM Role r WHERE r.email=:emailparam AND r.password=:passwordparam"); 
    checkEmailExists.setParameter("emailparam", email); 
    checkEmailExists.setParameter("passwordparam", password); 
    int matchCounter = 0; 
    matchCounter = checkEmailExists.getResultList().size(); 
    if (matchCounter == 1) { 
     return true; 
    } 
    return false; 
} 

回答

1

你不應該拋出的JSF ValidatorException內的EJB方法,但是在JSF validate()方法中。

我不確定在導致此異常的EJB中出了什麼問題,可能getSingleResult()根本沒有返回單個結果(因此爲零或多個)。您需要相應地更改/處理此問題,方法是使用getResultList()或修改您的數據模型爲什麼用戶沒有單一角色。我想你只需要getResultList(),因爲你顯然允許null結果。

+0

我現在使用getResultsList(),並且我還檢查了查詢返回的內容。返回的只有一個Role實例。當authentificationEJB.checkCredentials(emailInput,passwordInput)被評估爲false時,validate方法已經拋出Validation異常。我不明白錯誤在哪裏。我的數據模型我認爲是可以的。我有3個用戶(買方,賣方和管理員),他們每個人都與角色有一對一的關係。角色實體包含變量email和密碼。 P.S(當我檢查證書時,查詢只能訪問角色實體) – sfrj 2011-04-13 17:10:04

+0

這只是一個猜測。答案在於拋出一個'ValidatorException'而忽略的捕獲異常。您需要記錄捕獲的異常以瞭解原因。如果你能處理它,那就做吧。如果你不能處理它,重新拋出它作爲一般/業務運行時異常或其他。 – BalusC 2011-04-13 17:30:12

+0

我想我們是彼此誤解。 **正確**是你現在的問題?編輯:當**沒有**單個結果時,更新的'checkCredentials()'會引發異常。你需要通過'return checkEmailExists.getResultList()。size()== 1;' – BalusC 2011-04-13 17:34:12

相關問題