Как реализовать проверку нескольких полей на моей странице входа (JSF 2.0)

#java #jsf #jakarta-ee #jsf-2 #java-ee-6

#java #jsf #джакарта-ee #jsf-2 #java-ee-6

Вопрос:

Мне нужна проверка нескольких полей для страницы входа (многие поля проверяются одновременно одним и тем же методом). Я не знаю, как это правильно реализовать. Я следую примеру, который я нашел по адресу: http://balusc.blogspot.com/2007/12/validator-for-multiple-fields.html

Я немного запутался в части JSF.Может кто-нибудь помочь мне, чего мне не хватает?

Страница:

 <h:form>
    <p:panel>
        <h:outputText value="*Em@il:" />
        <h:inputText id="email" value="#{securityController.email}"
            required="true" />
        <br />
        <h:outputText value="*Password: " />
        <h:inputSecret id="password" value="#{securityController.password}"
            required="true">
            <f:validator validatorId="loginValidator" />
        </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>
  

Это управляемый компонент с методом validate:

 @ManagedBean
@RequestScoped
public class SecurityController implements Validator {

    @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 validate,
            Object value) {
        String emailInput = (String) value;
        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 inputFromField = (String) value;
        String alphanumericPattern = "^[a-zA-Z0-9] $";
        Pattern passwordPattern = null;
        Matcher passwordMatcher = null;
        passwordPattern = Pattern.compile(alphanumericPattern);
        passwordMatcher = passwordPattern.matcher(inputFromField);
        if (!emailMatcher.matches() amp;amp; !passwordMatcher.matches()) {
            if (authentificationEJB.checkCredentials(email, password) == false) {
                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
        Role role = (Role) query.getSingleResult();
        if (role != null amp;amp; role.getEmail().equals(email)
            amp;amp; 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
        System.out.println(role.getEmail()   role.getPassword());
        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;
    }
}
  

Update

Removed LoginValidator

The modified managed bean:

 @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() amp;amp; !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("Zaboraviliste nesto");
            throw new ValidatorException(msg);
        }
        if (passwordInput.length() <= 0 || emailInput.length() <= 0) {
            FacesMessage msg = new FacesMessage("Zaboraviliste nesto");
            throw new ValidatorException(msg);
        }
    }
    // Get set methods
}
  

Форма входа:

 <h:form>
    <p:panel>
        <h:outputText value="*Em@il:" />
        <h:inputText id="email" value="#{securityController.email}"
            binding="#{emailComponent}" />
        <br />
        <h:outputText value="*Password: " />
        <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>
  

Изменен метод 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
    try {
        Role role = (Role) query.getSingleResult();
        if (role != null amp;amp; role.getEmail().equals(email)
            amp;amp; 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) {
        // This fix the bug that does not display the message when wrong
        // password!
        FacesMessage msg = new FacesMessage("Pogresan email ili lozinka");
        throw new ValidatorException(msg);
    }
    // 4-return false otherwise
    return false;
}
  

Ответ №1:

Вам нужно привязать первый компонент с помощью binding и передать его как атрибут компонента, который вы проверяете. Вам также необходимо использовать validator атрибут поля ввода вместо <f:validator> , когда вы хотите вызвать метод проверки внутри управляемого компонента. Наконец, вы должны избавиться от implements Validator в классе bean.

 <h:outputText value="*Em@il:" />
<h:inputText id="email" binding="#{emailComponent}" value="#{securityController.email}" required="true"/>                   
<br/>
<h:outputText value="*Password: " />
<h:inputSecret id="password" value="#{securityController.password}" validator="#{securityController.validateEmailAndPassword}" required="true">
    <f:attribute name="emailComponent" value="#{emailComponent}" />
</h:inputSecret> 
  

с помощью

 public void validateEmailAndPassword(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    UIInput emailComponent = (UIInput) component.getAttributes().get("emailComponent");
    String email = (String) emailComponent.getValue();
    String password = (String) value;

    // ...
}
  

Комментарии:

1. Я добавил LoginValidator как отдельный класс, не являющийся управляемым компонентом, и я удалил метод проверки из управляемого компонента. Я получаю исключение NullPointerException в LoginValidator, где написано:Строковый пароль = (строковое) значение; Почему это? нормально ли, что я также внедрил EJB в этот класс?

2. Эта строка может привести к невозможному запуску NPE. Это не другая строка или вы имели в виду, что значение равно null ? Если последнее, просто добавьте if (password != null) проверку перед доступом к нему / манипулированием им.

3. Извините, это строка 27, которая выдает NPE: String email = emailComponent.GetValue().toString();

4. Тогда emailComponent это null . Вы правильно ее привязали с помощью binding="#{emailComponent}" ?

5. Нет, я этого не делал, я забыл это. Я только что добавил привязку. Сейчас это работает нормально, но только когда я даю правильные учетные данные, когда учетные данные неверны или поле электронной почты пустое, я получаю NPE