Spring Boot Custom Annotation

Fatma Delen
3 min readSep 1, 2020

--

Merhabalar 🙋🏽,

Sizlere Spring Boot’da custom annotation oluşturmaktan bahsedeceğim. Spring Boot’ta, Spring Framework’teki klasik xml ayarları yerine anotasyonlar kullanılmaktadır.
Sınıflar, arayüzler, metodlar ve fieldlar için anotasyon kullanılabilir.

Unique bir field oluşturmak için anotasyon yazmak istiyorsak:
Öncelikle;
1-Bir interface oluşturmalıyız.

@Constraint(validatedBy = UniqueUsernameValidator.class)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UniqueUsername {

String message() default "This username is already exist";

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

Class<? extends Payload>[] payload() default { };
}

@Constraint anotasyonu yeni oluşturacağımız anotasyonun bir doğrulama kısıtlaması olarak kullanacağımızı belirtir. validatedBy attribute’si doğrulama mantığını içerecek bir sınıf bildirmek için kullanılır.

@Target anotasyonu, oluşturulan yeni anotasyonu nereye uygulayabileceğinizi açıklar. Örneğin aşağıdaki kod bir field doğrulamasında bu anotasyonun(UniqueUsername) kullanılabileceğini göstermektedir.

messsage() →Hata mesajları oluşturmak için varsayılan değeri döndürür.

Target anotasyonu için yukarıdaki değerleri de kullanabiliriz. Örneğin: ElementType.Parameter UniqueUsername anotasyonunu bir parametrede kullanılabileceğini gösterir.

2 → ConstraintValidator interface’inden implement alan bir sınıf oluşturmalıyız. Spring framework , ConstraintValidator interface’ini uygulayan tüm sınıfları otomatik olarak algılar. ConstraintValidator geneldir, bu yüzden burada nesne türlerimizi söylemeliyiz. Öncelikle anotasyonu ve ardından nesne türünü belirtmeliyiz. isValid() metodunu override etmeliyiz. (Bu metod iki parametre almakta, birincisi username alanının değeri olan string nesnesi ikincisi ise ConstraintValidatorContext’dir. Bu metodla mantığımızı uygulayıp true veya false değerini döneceğiz. Geçersiz bir istekle sonuçlanırsak false değerini döneceğiz.)

public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername,String> {

@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return false;
}
}

3 → Şimdi veritabanından girilen kullanıcı adına ait kullanıcı var mı diye kontrol edelim. Eğer yoksa true, varsa false değerini döndürmeliyiz.

@Autowired
UserRepository userRepository;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
User user = userRepository.findByUsername(value);
if(user == null){ // eğer kullanıcı yoksa
return true;
}
return false;
}

4 → Artık oluşturduğumuz anotasyonu username field’ında kullanabiliriz.

@UniqueUsername
private String username;
Projeyi bu haliyle çalıştırdığımızda yukarıdaki hatayı alacağız. (Veritabanında herhangi bir kısıtlama işlemediğimiz için bu hatayı alıyoruz)

5 → Hibernate doğrulama davranışını devre dışı bırakalım.

jpa:
properties:
javax:
persistence:
validation:
mode: none

Tekrar çalıştıralım.

Eğer dönen mesaj tipini uluslararası yapmak istiyorsak:

  • UniqueUsername class’ında yer alan message değerini aşağıdaki gibi güncellemeliyiz.
String message() default "{social.constraint.username.UniqueUsername.message}";
  • Daha sonra resources klasörü altında ValidationMessages.properties adında bir file oluşturmalıyız. Bu file’a aşağıdaki kodu eklemeliyiz.
social.constraint.username.UniqueUsername.message = This username is already exist
  • Türkçe karşılığı için ValidationMessages_tr.properties adında bir file oluşturmalıyız. Bu file’a aşağıdaki kodu eklemeliyiz.
social.constraint.username.UniqueUsername.message = Bu kullanici adi zaten mevcut
Postman’de Accept-Language kısmına tr setlersek gelen mesajın Türkçe olduğunu görebiliriz.

Bu makaleyi buraya kadar okuduğunuz için teşekkür ederim 😇.

--

--