Weryfikacja danych w walidatorze i springowy walidator jak component.

0

Witam. Napisałem sobie swój walidator, aby sprawdzić poprawność danych wprowadzonych przez użytkownika, tj. czy imię nie zawiera cyfr, czy format adresu email jest poprawny itp. Jednak jeszcze potrzebuję zweryfikować z bazą danych czy login jaki podał użytkownik nie istnieje już w bazie. Czyli nie wystarczy już porównać wprowadzonych danych do inputa na stronie ze wzorcem i trzeba przeszukać bazę używając dao. Nie wiem czy dobrze to zrealizowałem bo postanowiłem wstrzyknąć do walidatora swój serwis userService, który wywołuje metody dao i wyszukuje czy nie istnieje użytkownik o podanym loginie. Wygląda to mniej więcej tak:

@Component
public class UserValidator implements Validator {

	@Autowired
	UserService userService;

	@Override
	public boolean supports(Class<?> clazz) {
		return UserDto.class.equals(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		UserDto user = (UserDto) target;


		if ((user.getUsername() != null) && (!user.getUsername().isEmpty())) {
			String username = user.getUsername();
			if ((username.length() < 3) || (username.length() > 40)) {
				errors.rejectValue("username", "username.format");
			} else if (userService.findByUsername(username) != null) {
				errors.rejectValue("username", "username.duplicate");
			}
		}
	}
}
 

Czy takie podejście jest dobre? Tzn. takie robienie komponentu z walidatora i wstrzykiwanie do niego serwisu?

Pamiętam, że w czystej JEE robiłem to trochę inaczej bo chyba ktoś z tego forum mi doradził, że w walidatorach należy sprawdzać poprawność wprowadzonych danych, ale weryfikacje czy np. nie istnieje użytkownik o identycznym loginie itp. należy przenieść do serwisu. Tak też tam robiłem, że miałem klasę serwisową, która sprawdzała czy taki użytkownik istnieje i jeśli istniał to zwracała Stringa z komunikatem np. "Użytkownik o podanym loginie istnieje" i w managed beanie dodawałem errora do kontekstu.
Czyli takie rozwiązanie jak powyżej dałem raczej jest niepoprawne i powinien to zmienić na coś w stylu jak robiłem to w JEE?

Jeszcze jedna sprawa dotycząca wyświetlania komunikatów, mianowicie pojawienie się komunikatów o błędzie przy formularzu trochę "rozbija" mi ten formularz mimo tego, że tekst mieści się w 1 linii. Przypuszczam, że dzieje się tak bo dodaje się jakieś takie dziwne podkreślenie pod tym komunikatem. Na innych tutorialach tego nie widziałem. Jak się tego pozbyć? Screen jak to wygląda w załączniku.

				<form:label path="username">Login: </form:label>
				<form:input path="username" />
				<form:errors path="username" cssClass="error" /> 

Klasa error w css na wszelki wypadek:

.error {
	color: red; 
	font-size: 0.9em; 
	font-weight: bold; 
	width: 200px;
} 
1

Tak jak pisałem w temacie o którym wspominasz: można to zrobić i tak i tak, ale zauważ taką sytuację:
Dwóch użytkowników jednocześnie próbuje dodać nowego użytkownika z tym samym loginem. Odpala się twój walidator, sprawdza, wszystko jest ok, następnie odpala sie metoda dodawania i jedna z transakcji się wysypuje bo użytkownik już istnieje. W efekcie I TAK musisz obsłużyć błąd serwisu UserService który ma metodę createNewUser() i wypisać błąd użytkownikowi. Po co więc była ta cała walidacja skoro guzik dała? :) Bo widzisz zastosowałeś tu klasyczny błąd "check then act" i nie wziąłeś pod uwagę że pomiędzy twoim "sprawdzeniem" a "akcją" może się wiele zmienić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1