Michał Borek

Tech blog

Opera 10.50

Światło dzienne ujrzała nowa wersja przeglądarki Opera, oznaczona numerkiem 10.50 (zamiennie z 10.5 ;)).

Biorąc pod uwagę spowolnioniony rozwój i “rewolucyjność” kolejnych wersji Opery w przeciągu ostatniego roku, wersja 10.50 jest rewolucyjna.

Do głównych zalet zaliczyłbym:

  • Karty na pasku tytułu (Win7 style).
  • Niesamowita szybkość JavaScriptu (nowy silnik JS).
  • Lepsze uzupełnianie na pasku adresów.
  • Większa możliwość zmiany wyglądu (przyciski na dole ekranu itd.).
  • Lepsze wsparcie dla DragonFly (“Przegląd elementu”).
  • No i coś, czego nie było chyba tylko w Operze, Porno Browsing (ups. Private Browsing :)).

Deweloperzy Opery narzucili bardzo szybkie tempo, jeżeli chodzi o wydawanie kolejnych wersji alpha, beta i RC, co skutkowało szybkim wykrywaniem błędów i wypuszczeniem nowej Opery w tak krótkim czasie (pierwsza wersja alpha ujrzała światło dzienne na przełomie lat 2009/2010 .

Entuzjastą Opery jestem stosunkowo od niedawna, ale mam nadzieję, że zostanę na długo. Czasem jeszcze muszę włączyć starego, poczciwego Firefoksa, ale fakt że w międzyczasie mogę zrobić sobie herbatę jakoś nie nastraja mnie pozytywnie :).

SCJP zdany!

Po 10 dniach ciężkich przygotowań do certyfikatu SCJP udało się zdać egzamin na 86%. Ulżyło mi, gdyż poziom szczegółowości pytań był bardzo duży, a pytania skonstruowane tak, że łatwo było się pomylić lub zabrnąć w ślepy kąt.

Jeżeli Oracle nic nie wymyśli i nie zrezygnuje z certyfikacji w takiej formie, jaka jest teraz, to niedługo zaczynam naukę do SCWCD (Sun Certified Web Component Developer). Biorąc pod uwagę fakt, że będąc na studiach mam dość dużo czasu, trzeba to jakoś wykorzystać.

SCJP

Walidacja identyczności haseł – Hibernate Validator, Spring Framework

Natknąłem się na problem walidacji identyczności haseł w formularzu rejestracji użytkownika. Korzystam ze Spring Frameworka, a do walidacji wykorzystuję bibliotekę Hibernate Validator w wersji 4.

Pierwszym problemem okazał się brak pola confirmPassword w klasie User. Poszperałem na forach i znalazłem w rozwiązania tego problemu:

  • Stworzyć dodatkowe pole w klasie User – confirmPassword
  • Stworzyć dodatkową klasę, przypuśćmy CreateUserForm, mniej więcej tak:
1
2
3
4
5
class CreateUserForm {
    String confirmPassword;
    User user;
    (... )
}

Rozwiązanie to wydaje mi się “ładniejsze” niż pierwsze, gdyż nie tworzymy w klasie, wykorzystywanej przy każdym requescie pola, które w ogóle nam jest niepotrzebne.

Kolejnym problemem okazała się walidacja. Chcieliśmy w 100% korzystać z funkcjonalności, jakie dają nam adnotacje z Hibernate Validatora. Brakuje jednak tam adnotacji umożliwiającej porównywanie ze sobą 2 pól.

Tutaj też skorzystałem z forów. Jedna osoba z teamu hibernate poleciła mi wykorzystanie ograniczeń (constraints) przypisanych do klas i zmianę domyślnego błędu zwracanego przez ten walidator.

Poniżej przedstawię rozwiązanie od jakiego doszedłem:

Poniżej znajduje się definicja interfejsu odpowiedzialnego za adnotację @SamePassword:

1
2
3
4
5
6
7
8
@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = SamePasswordValidator.class)
public @interface SamePassword {
    String message() default "{pl.aetas.gamestore.validator.constraint.SamePassword}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Sama klasa walidatora wygląda tak:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class SamePasswordValidator implements ConstraintValidator<SamePassword, Object> {

    SamePassword constraintAnnotation;

    public boolean isValid(Object value, ConstraintValidatorContext context) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(constraintAnnotation.message()).addNode("confirmPassword").addConstraintViolation();
        CreateUserForm u = (CreateUserForm) value;
        if (u.getConfirmPassword().equals(u.getUser().getPassword())) {
            return true;
        }
        return false;
    }

    public void initialize(SamePassword constraintAnnotation) {
        this.constraintAnnotation = constraintAnnotation;
    }
}

Aby skorzystać z w/w rozwiązania wystarczy w klasie CreateUserForm dodać adnotację @SamePassword (na poziomie klasy) i .. tyle.

Mam nadzieję, że komuś się to przyda. W naszym projekcie adnotacje znacznie zwiększyły czytelność kodu, a jest to bardzo istotne przy pracy grupowej.