#java #jsf #jakarta-ee #jsf-2 #java-ee-6
#java #jsf #джакарта-ee #jsf-2 #java-ee-6
Вопрос:
У меня есть механизм входа, состоящий из страницы JSF управляемого компонента EJB, он работает нормально, но единственная ошибка заключается в том, что я не вижу сообщения об ошибке, когда пароль введен неправильно. Есть идеи?
Когда пароль введен неправильно, это то, что я получаю в браузере:
Я могу избежать этого, если не буду создавать исключение ValidationException при перехватывании в EJB (см. Код EJB ниже), но тогда я вообще не вижу никакого сообщения о проверке в форме, когда пароль введен неправильно.
Это код для формы на странице:
<h:form>
<p:panel>
<h:outputText value="*Em@il:" />
<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() 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("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 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) {
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, я думаю, что совершаю ошибку, если я создаю исключение ValidationException в блоке catch, потому что я думаю, что отображение сообщений об ошибках во внешнем интерфейсе должно быть задачей для управляемого компонента. Я не понимаю, почему форма не отображает ошибку, как это происходит, когда поля пусты при неправильном вводе пароля (когда электронное письмо неверно, оно корректно отображает сообщение о проверке).
Обновить
Изменен метод 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 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
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
результат.
Комментарии:
1. Теперь я использую getResultsList () и я также проверил, что возвращается из запроса. Возвращен только один экземпляр Role. Метод validate уже выдает исключение проверки, когда authentificationEJB.checkCredentials(emailInput, passwordInput) принимает значение false. Я не понимаю, в чем ошибка. Я думаю, что моя модель данных в порядке. У меня есть 3 пользователя (покупатель, продавец и администратор), у каждого из них есть отношения OneToOne с Role. Объект роли содержит переменные email и password. P.S (Когда я проверяю учетные данные, запрос обращается только к объекту роли)
2. Это было просто предположение. Ответ заключается в обнаруженном исключении, которое вы проигнорировали, выдав
ValidatorException
. Вам необходимо зарегистрировать обнаруженное исключение, чтобы узнать о причине. Если вы можете с этим справиться, сделайте это. Если вы не можете с этим справиться, перенаправьте его как какое-либо общее исключение / исключение бизнес-среды выполнения или что-то в этомроде.3. Я думаю, мы неправильно понимаем друг друга. В чем именно заключается проблема, с которой вы столкнулись сейчас? Редактировать: ваше обновленное приложение
checkCredentials()
выдаст исключение, когда не будет ни одного результата. Вам нужно заменить все это наreturn checkEmailExists.getResultList().size() == 1;
4. Точная проблема сейчас заключается в том, что при входе в систему не отображается ошибка проверки при неправильных учетных данных. Я изменил метод saveUserState (), а также checkUserCredentials(), но я думаю, что ошибки там нет. Я думаю, что проблема в управляемом компоненте, где по какой-то причине ошибка не регистрируется, когда это подтверждается значением true: if (authentificationEJB.checkCredentials(emailInput, passwordInput)
5. Исключений нет, я уверен, что размер возвращаемого списка всегда равен 1 (см. Обновление). Также я уверен, что в базе данных, которую я только что проверил, нет дубликатов.