Loading...
lapd87 avatar lapd87 103 Точки

[Homework] Java Spring Auto Mapping - 01. Problem - Game Store

Привет,

моля някой ако може да погледне кода ми и да каже защо не ми работят валидаторите (говорим мейл и парола). Предполагам грешката е една и съща, но гледах видеото от упражненията на Иван, гледах и примерите от слидо не успявам да намеря разлика.

https://www.dropbox.com/s/j3kbushhp9p9xd4/_01GameStore.zip?dl=0

 

Весело прекарване на празника на всички :)

Тагове:
1
Module: Java DB
k.sevov avatar k.sevov 1077 Точки

Edit: Какво тествах и аз не знам... Бях написал глупости, присъединявам се и аз към въпроса, тъй като си нямам идея защо се получава така. 

0
07/04/2018 11:02:24
lapd87 avatar lapd87 103 Точки

:) тъкмо видях какво написа и викам ще оправям ама ...

още нещо добавям предполагам отговора ще е същия,  но това също не се изпълнява като проверка

@Size(min = 0, message = "Size must be positive")

https://github.com/AtanasYordanov/JavaDB-Frameworks---Hibernate-Spring-Data/blob/master/10.Spring%20Data%20Auto%20Mapping/src/main/java/app/services/impl/UserServiceImpl.java

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

0
07/04/2018 13:49:55
k.sevov avatar k.sevov 1077 Точки

Да, точно до това достигнах и аз сега. Бях пропуснал, че validator.validate() не хвърля exception, а връща колекция от грешки, където вече да се провери дали има някакви. Значи все пак се оказва, че работи ако го направим така "ръчно" с autowire на Validator и само да се сложат анотациите не е достатъчно.

1
MartinBG avatar MartinBG 4803 Точки

Не съм се заглеждал много в кода ти, но на пръв поглед ти липсват параметрите, по които да правиш валидацииите.

 

Тук съм качил работещи анотации към една от по-старите задачи, които може да ползваш за вдъхновение :)

1
lapd87 avatar lapd87 103 Точки

Ами огледах но честно казано не схванах какво точно се случва...

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

 

И има ли вариант при провал на проверката да ми хвърля грешката само, а не една камара съобщение?

0
07/04/2018 20:51:22
MartinBG avatar MartinBG 4803 Точки

Проверката се прави автоматично при записване в базата на полето, анотирано директно или чрез гетъра:

    @Column(nullable = false)
    @Password(minLength = 6,
            maxLength = 50,
            containsDigit = true,
            containsLowerCase = true,
            containsUpperCase = true,
            containsSpecialSymbols = true)
    public String getPassword() {
        return this.password;
    }

Ако някое от горните условия не бъде изпълнено, записа в базата ще хвърли ексепшън с грешката, която е сетната в анотацията (това е и смисъла от това да имаме различни съобщения за различните проверки).

Например, при опит за записване в базата на юзър, с парола без специален символ, ще получим тази грешка:

Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [user.models.entities.User] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Password should contain one of: !@#$%^&*()_+<>?', propertyPath=password, rootBeanClass=class user.models.entities.User, messageTemplate='Password should contain one of: !@#$%^&*()_+<>?'}
]

Дали ще я вхащаме и как ще я обработваме, или ще оставим приложението да крашне, зависи от конкретните ни цели.

(Добрата практика изисква такива грешки да бъдат хващани и обработвани там, където са предизвикани - напр. на мястото, от където са подадени невалидните данни, защото най-често там има най-много информация за причините за възникването им и съответно може да се вземе правилно решение за обработването им: най-често съобщение към потребителя и/или логване на събитието).

 

1
08/04/2018 05:39:54
lapd87 avatar lapd87 103 Точки

Съжелявам ама пак нищо не разбрах от обясненията :)

пуснах си видеото от предния курс и на 1:48:00 откриха топлата вода. Имплементирах си го и след добавяне на депенданси проработи перфектно :)

<!-- https://mvnrepository.com/artifact/org.glassfish.web/el-impl -->
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>el-impl</artifactId>
    <version>2.2</version>
</dependency>

в имплементацията на регистрирането след като наглася user правя валидацията и всичко е ок

user.setRole(role);

ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Set<ConstraintViolation<User>> constraintViolations = validatorFactory.getValidator().validate(user);

if (!constraintViolations.isEmpty()) {
    for (ConstraintViolation<User> constraintViolation : constraintViolations) {
        System.out.println(IODelimiter + constraintViolation.getMessage());
    }

    return false;
}

this.userRepository
        .saveAndFlush(user);

return true;
1
lapd87 avatar lapd87 103 Точки

всичко хубаво си има край. Като сложих ограниченията за игрите и се получи следния проблем при нова игра

HV000030: No validator could be found for constraint 'javax.validation.constraints.Size' validating type 'java.lang.Double'. Check configuration for 'size'

като се сменяше на BigDecimal за цената и т.н.

хвърля ексепшъна при

Set<ConstraintViolation<Game>> constraintViolations = validatorFactory.getValidator().validate(game);

За целта оправих така:

@Size(min = 0, message = "Size must be positive")
@Column(nullable = false, scale = 1)

@Range(min = 0, message = "Price must be positive")
@Column(nullable = false, scale = 2)

сега гърми с 

javax.validation.ValidationException: HV000032: Unable to initialize softuni.gamestore.model.validators.TrailerCheckValidator.

не ми е ясно какво се случва....

Идеи?

Ето проекта към момента

https://www.dropbox.com/s/j3kbushhp9p9xd4/_01GameStore.zip?dl=0

 

Edit:

Видях че имам проблем с регекса на трейлъра и го оправих:

return trailer.matches("^\\w{11}$");

освен това оправих логиката при добавяне и редактиране на игра да поема цял линк и само края:

String[] trailerInput = inputArgs[4].split("=",2);

String trailer = trailerInput[0];
if (trailerInput.length > 1) {
    trailer = trailerInput[1];
}

но все още грешката е същата...

Видях че от копи-пейст е останало в трейлъра на заглавието класовете... тъпо ама го оправих и него

сега пак се връщаме на грешките с Double...

малко гугъл и ето това е решението за големина и цена:

@DecimalMin(value = "0.0", inclusive = true, message = "Price must be positive")

 

Весел празник ето линка на оправената задача :) Благодаря отново на всички отзовали се, без вас нямаше да успея :)

https://www.dropbox.com/s/j3kbushhp9p9xd4/_01GameStore.zip?dl=0

2
08/04/2018 14:17:34
MartinBG avatar MartinBG 4803 Точки

Опитваш се да изпълниш условието за прецизност (символи след десетичната зашетая) за цена и размер, предполагам. :)

Тука има няколко подхода, които могат да се разделят най-общо на две групи:

А. Валидация на входните данни

Б. Валидация на ниво ентити + сетване на колоните в таблиците на базата с желаната прецизност

В. Комбинация между горните две

Входните данни може да се проверяват на няколко места: при прочитането, при конструирането на DTO, при подаването за запис към базата. Най-смислено, според мен, в този случай е проверката да бъде в DTO, като всякакви грешки, открити там се връщат към потребителя.

Системата ще работи и при правилно създадено ентити с валидация на всяко поле - това е най-лесно за реализация и като цяло не е лоша идея да го има, дори и да правим валидацията на други нива (един вид застраховка, ако някой опита да persist-не обект, създаден по нестандартен начин).

По-трудно е за поддръжка, но това може да се адресира, ако си направим анотации за проверка на всяко поле и използваме само и единствено тях на всяко от нивата в програмата ни (напр. @Password, @Email, @URL и т.н., които да ползваме както за entity, така и за dto). 

 

Относно задаването на прецизност за числата в базата през Hibernate, аз знам за 2 начина:

1. Използване BigDecimal тип в entiti-то и към него подбна анотация: @Column(precision = 10, scale = 1)

2. Сетване на типа директно чрез анотация, като това работи и за float/double, но не е добра идея, защото е един вид хардкодване и може да не работи на друга база : @Column(columnDefinition = "DOUBLE(10,1)")

2
lapd87 avatar lapd87 103 Точки

Благодаря че го видя

@Digits(integer = 20, fraction = 1, message = "Invalid size format")

добавих това :) мисля че е най-лесно

1
nickhub avatar nickhub 0 Точки

Nice to see this here and thanks for sharing this to us. websites like rabbit  is given here to check.

 

-1
19/09/2019 14:42:50 1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.