infolightbulb_outlinenew_releasesreportwarning

Java Web Uygulamalarında Doğrulama Yöntemleri

Adilcan Eren

Bean Validation

  • Standart Java doğrulama spesifikasyonu

  • Ek Açıklama bazlı çalışan bir mekanizma

  • Alan, metot, parametre ölçeğinde kısıtlar sağlıyor

  • Java SE/EE versiyonları ile çalışabiliyor

Bean Validation

  • Ek Açıklamaların üstveriyi ezme/miras alma imkanı var

  • Kısıtlamaya çalıştığımız problemler (çoğunlukla) öntanımlı

  • Yeniden kullanılabilir: aynı ihtiyaç için birden fazla özel kısıt yazmak verimsiz

  • Doğrulamayı veritabanına bırakmak daha maliyetli, hataları idame etmek zor

Bean Validation 1.0

  • JSR 303

  • Java EE 6

  • 2009

  • İlk obje doğrulama standardı

  • Özellik ve "bean" seviyesinde doğrulama

  • Özel doğrulayıcı yazılabiliyor

  • Hazır i18n desteği

Bean Validation 1.1

  • JSR 349

  • Java EE 7

  • 2013

  • Metot seviyesinde doğrulama (parametre, dönüş değerleri)

  • Bağımlılık enjeksiyonu desteği

  • CDI entegrasyonu

  • EL ile hata mesajlarını yönetebilme

Bean Validation 2.0

  • JSR 380

  • Java EE 8

  • 2017

  • Parametre içinde ek açıklama kullanımı

  • JavaFX desteği

  • Tarih değişkenleri

Hibernate Validator

  • Referans implementasyon

  • Apache 2.0

  • Ek özellikler sunuyor

  • Programa dayalı kısıt tanımları

  • Ek Açıklama işleyici

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.16.Final</version>
</dependency>

Ek Açıklama İşleyici

  • Derleyici ile etkileşen bir mekanizma

  • Ek Açıklama hatalı biçimde kullanılırsa hata fırlatıyor.

  • Çeşitli kriterleri derlenme zamanında kontrol ediyor:

  • Sadece izin verilen tiplerde kullanılabilir.

  • Statik alanlarda kullanılamaz.

  • İlkel tiplerde @Valid kullanılamaz.

  • Parametre değerleri geçerli olmalıdır.

Üstveri

  • Alanlar, metotlar, ek açıklamalar

  • Doğrulanacak her obje için üstveriye ihtiyaç var

  • Üstveri uygulama başlatılırken alınıyor, amaç maliyet azaltmak

  • javax.validation.metadata altında tanımlı

  • Bu paket ile üstveriye ait özelliklere ulaşabiliyoruz.

Kullanım

Alan seviyesinde kullanım

public class User {
    @NotNull
    private String username;

    @Email(message = "Email must be valid")
    private String email;

    @Min(value = 18)
    @Max(value = 100)
    private int age;

    @Size(min = 8, max = 42)
    private String password;

}

Metot seviyesinde kullanım

@AssertTrue
public boolean isVerified() {
...
}

@NotNull
public String getUsername() {
...
}

Parametre seviyesinde kullanım

List<@Positive Integer> ageList;

Map<@Currency MonetaryAmount, @Positive BigDecimal> values;

Cat(@NotNull name) {
}

Sınıf seviyesinde kullanım

@PasswordMatches
public class User {
...
}

Özel Ek Açıklama Yazımı - 1

@Target({ METHOD, FIELD, TYPE, PARAMETER, CONSTRUCTOR})

@Retention(RUNTIME)

@Constraint(validatedBy = {PasswordValidator.class})

public @interface PasswordMatches {

    String message() default "Passwords must match.";

    Class<?>[] groups() default { };

}

Özel Ek Açıklama Yazımı - 2

public class PasswordValidator implements ConstraintValidator<PasswordMatches, Object> {
  ...
  @Override
  public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
      //Wrap object to type
      return o.getPassword().equals(o.getMatchingPassword());
  }

XML ile Kısıt Tanımı

<?xml version="1.0" encoding="UTF-8"?>
<validation-config
        xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration validation-configuration-2.0.xsd"
        version="2.0">

        <bean class="User">
        <field name="username">
            <constraint annotation="javax.validation.constraints.NotNull"/>
        </field>
        <field name="password">
            <constraint annotation="javax.validation.constraints.Min">
                <element name="value">8</element>
            </constraint>
        </field>

</validation-config>

İfade Dili Kullanımı

@NotEmpty(message = "{common.not_empty}")
private String name;

@Size(min = 10, message = "Description '${validatedValue}' must be at least {min}" +
" characters. Current length: '${validatedValue.length()}'")
private String description;

Programa Dayalı Kısıt Tanımları

  • Standard, XML ve ek açıklama bazlı kısıtlara izin veriyor.

  • Hibernate Validator programa dayalı kısıt uygulayabilmeyi de sağlıyor.

HibernateValidatorConfiguration config = Validation
        .byProvider(HibernateValidator.class)
        .configure();

ConstraintMapping mapping = config.createConstraintMapping();

mapping
    .type(User.class)
        .property("username", FIELD)
            .constraint(new NotNullDef())
        .property("password", FIELD)
            .ignoreAnnotations(true)
            .constraint(new NotNullDef())
            .constraint(new SizeDef().min(8).max(42));

Validator validator = config.addMapping(mapping)
        .buildValidatorFactory()
        .getValidator();

JSF ile Doğrulama

<h:inputText id="email" value="#{user.username}" validatorMessage="Username can only contain letters numbers, dashes, underscores.">
    <f:validateRegex pattern="^[a-zA-Z0-9._-]{3,}$"/>
</h:inputText>

<h:inputSecret id="password" value="#{user.password}" validatorMessage="Password must contain at least 8 characters.">
    <f:validateLength minimum="8" maximum="42"/>
</h:inputSecret>

<h:inputText id="age" value="#{user.age}" validatorMessage="You must be at least 18 years old.">
    <f:validateLongRange minimum="18" maximum="100"/>
</h:inputText>

Soru-Cevap