Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

MartinBG avatar MartinBG 4803 Точки

[Exercise - Employee Register] - Решение с валидация

Здравейте, колеги!

 

И в трите домашни от това упражнение, които ми се падна да проверя, забелязах, че не е изпълнена следната част от условието:

If there is an empty field, NOTHING should happen, and NO Employee should be added.

 

Понеже и аз имах известни проблеми с имплементирането ѝ, реших да споделя моето решение.

 

Правим си binding модела с валидациите, както си го знаем:

public class EmployeeRegisterBindingModel {

    @NotNull
    @Size(min = 1, max = 32)
    private String firstName;

    @NotNull
    @Size(min = 1, max = 32)
    private String lastName;

    @NotNull
    @Size(min = 1, max = 32)
    private String position;

    @NotNull
    @Min(0)
    private BigDecimal salary;

    @NotNull
    @Min(0)
    private Integer age;

    // constructor, getters, setters
}

 

При натискане на "Register", данните ще бъдат валидирани, а при невалидни данни заявката ще бъде игнорирана (без да се нулират полетата:), с грешка като тази в лога:

16-Feb-2019 17:02:34.176 WARNING [http-nio-8000-exec-2] org.apache.myfaces.lifecycle.RenderResponseExecutor.execute There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
These unhandled FacesMessages are: 
- j_id_h:salary: must be greater than or equal to 0
- j_id_h:age: must be greater than or equal to 0

 

Освен валидациите на модела, може да добавим и валидации на полетата във формата, например required="true":

<p:inputText value="#{...}" id="..." placeholder="..." required="true"/>

 

При натискане "Register" ще бъде направена валидация на полетата, като при грешка заявката ще бъде игнорирана, а в лога ще получим описание на проблема. Напр.:

16-Feb-2019 17:10:22.527 WARNING [http-nio-8000-exec-6] org.apache.myfaces.lifecycle.RenderResponseExecutor.execute There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
These unhandled FacesMessages are: 
- j_id_h:firstName: Validation Error: Value is required.
- j_id_h:lastName: Validation Error: Value is required.
- j_id_h:position: Validation Error: Value is required.
- j_id_h:salary: Validation Error: Value is required.
- j_id_h:age: Validation Error: Value is required.

 

Двата типа валидации работят заедно, като първо се прави валидацията на input полетата, а после - на binding модела (само за полета, които са минали първата валидация).

Комбиниран лог:

16-Feb-2019 17:11:56.334 WARNING [http-nio-8000-exec-8] org.apache.myfaces.lifecycle.RenderResponseExecutor.execute There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
These unhandled FacesMessages are: 
- j_id_h:firstName: Validation Error: Value is required.
- j_id_h:lastName: Validation Error: Value is required.
- j_id_h:position: Validation Error: Value is required.
- j_id_h:salary: must be greater than or equal to 0
- j_id_h:age: must be greater than or equal to 0

 

 

В конкретната задача имаше и един допълнителен проблем, поне при мен.

При натискане на Delete бутона, се активираше валидацията на binding модела, която съответно не минаваше за празна форма и заради това не сработваше изтриването.

 

Решението (за PrimeFaces) беше да добавя immediate="true" като параметър към commandButton-а, който трие записи:

<p:commandButton value="Remove" immediate="true" action="#{...}"/>

 

Накрая - бонус съвет при използването на "PrimeFaces".  :)

Aко не искате да ви се променя стилизацията на елементите, когато използвате PrimeFaces, добавете следната директива към web.xml:

 

    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>none</param-value>
    </context-param>

 

Поздрави!

Тагове:
4
Module: Java Web
Ivelin_Dimitrov avatar Ivelin_Dimitrov 148 Точки
Best Answer

Добра работа Мартине, за тези валидации не сe говори много на лекциите и вярвам, че тази статия ще е полезна на много хора. 

В допълнение бих добавил само, че в jsf може да си валидираме данните с f:validate, като има различен набор от валидации validateLength, validateLongRange, validateDoubleRange.. Съответно можем да визуализираме message-те с 

<h:message id="m3" for="color" style="color:red; margin: 0 auto;"/>

Пример за такава jsf валидация

<div class="row">
   <div class="col-md-12 d-flex justify-content-center">
     <div class="form-group">
       <h:outputLabel for="age" value="Age"/>
       <p:inputNumber id="age" value="#{createCatManageBean.bindingModel.age}" styleClass="form-control-range"
                  required="true" validatorMessage="Age must be an integer between 1 and 31." label="Age">
            <f:validateLongRange maximum="31" minimum="1" for="age"/>
         </p:inputNumber>
     </div>
   </div>
   <h:message id="m4" for="age" style="color:red; margin: 0 auto;"/>
</div>

 За да не ни изписва съобщения от сорта на "- j_id_h:age:...." се добавя 'label=Age', с 'require="true" си гарантираме, че полето не може да бъде празно, като генерираното съобщение ще бъде "Age: Validation Error: Value is required.". Също така поставяме допълнителна валидация 

<f:validateLongRange maximum="31" minimum="1" for="age"/>

Която ни валидира полето да е в диапазона от 1 до 31 включително. Като допълнително сме указали какъв да е messege-а ако валидацията фелне с атрибута 

validatorMessage="Age must be an integer between 1 and 31."

 и накрая посочваме къде да се визуализира error message-а ако има такъв

<h:message id="m4" for="age" style="color:red; margin: 0 auto;"/>

Това съвсем не е единственият начин, можем да падаваме errorMessages от managed Bean-а към jsf-а като го добавим в FacesContext-a примерно за логин: 

//If login failed, should show errorMessage with "Invalid credentials."
if (userServiceModel == null) {
   FacesContext facesContext = FacesContext.getCurrentInstance();

   //Send an error message on Login Failure
   facesContext.addMessage(null, new FacesMessage("Invalid credentials."));
   return;
}

 съответно в jsf-а го прихващаме и рендерираме отново с h:message 

 <!-- Show authentication failed error message -->
 <h:messages globalOnly="true" style="color: red; margin: 8px; text-align: center" />

 

2
18/02/2019 13:18:31
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.