Gereksinimler ve Ön Hazırlık
Spring Boot üzerinde validation işlemlerini gerçekleştirmek için projenizde gerekli bağımlılıkların tanımlı olması gerekir. 2026 yılı standartlarına göre, Spring Boot 3.x sürümlerinde "spring-boot-starter-validation" bağımlılığı, Jakarta Bean Validation API'sini projenize dahil eder.
Projenizin pom.xml dosyasına aşağıdaki bağımlılığı ekleyerek işe başlayın:
org.springframework.boot
spring-boot-starter-validation
Bu bağımlılık, Hibernate Validator'ı varsayılan doğrulayıcı olarak projenize ekler. Kurulumun ardından, projenizi derleyerek bağımlılıkların indirildiğinden emin olun. Java 17 veya daha güncel bir sürüm kullanmanız, modern dil özelliklerinden tam verim almanızı sağlayacaktır.
Adım Adım Model Doğrulama (Bean Validation)
Veri doğrulama işleminin temel taşı, DTO (Data Transfer Object) sınıflarınızın üzerine eklediğiniz kısıtlayıcı (constraint) anotasyonlardır. Bu anotasyonlar, verinin hangi kurallara uyması gerektiğini bildiren deklaratif ifadelerdir.
Aşağıdaki örnekte, bir kullanıcı kayıt işlemi için temel doğrulama kurallarını içeren bir DTO sınıfı tanımlıyoruz:
import jakarta.validation.constraints.*;
public class UserRegistrationDto {
@NotBlank(message = "Kullanıcı adı boş bırakılamaz")
@Size(min = 3, max = 20, message = "Kullanıcı adı 3 ile 20 karakter arasında olmalıdır")
private String username;
@Email(message = "Geçerli bir e-posta adresi giriniz")
@NotBlank(message = "E-posta adresi zorunludur")
private String email;
@Min(value = 18, message = "18 yaşından küçükler kayıt olamaz")
private int age;
// Getter ve Setter metotları
}
Bu kod bloğunda @NotBlank, @Size, @Email ve @Min gibi anotasyonlar kullanılmıştır. Bu anotasyonlar, Spring Boot'a gelen verinin bu kriterleri karşılaması gerektiğini söyler. Eğer karşılamazsa, sistem otomatik olarak bir hata fırlatacaktır.
Controller Katmanında Doğrulama Süreci
Model üzerinde tanımladığımız kuralların tetiklenmesi için Controller sınıfında @Valid anotasyonunu kullanmamız gerekir. Bu anotasyon, Spring'e gelen isteğin gövdesini (request body) doğrulaması talimatını verir.
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping("/register")
public ResponseEntity registerUser(@Valid @RequestBody UserRegistrationDto userDto) {
return ResponseEntity.ok("Kullanıcı başarıyla kaydedildi.");
}
}
Burada @Valid anotasyonu, userDto nesnesi işlenmeden önce tüm kısıtlamaların kontrol edilmesini sağlar. Eğer bir kısıtlama ihlal edilirse, Spring Boot varsayılan olarak 400 Bad Request hatası döndürecektir.
Güvenlik Uyarısı: Sadece sunucu tarafında doğrulama yapmak yeterli değildir. Kullanıcı deneyimini artırmak için istemci tarafında da (Frontend) benzer kuralları uygulamalısınız. Ancak, güvenlik için asıl denetim noktası her zaman sunucudur; istemci tarafındaki doğrulamalar kolaylıkla atlatılabilir.
Global Hata Yönetimi
Varsayılan hata mesajları kullanıcı dostu olmayabilir veya uygulamanızın API standartlarına uymayabilir. @ControllerAdvice kullanarak tüm doğrulama hatalarını merkezi bir noktadan yakalayıp özelleştirebilirsiniz.
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity handleValidationExceptions(MethodArgumentNotValidException ex) {
Map errors = new HashMap();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage()));
return ResponseEntity.badRequest().body(errors);
}
}
Bu yapı, doğrulama hatalarını JSON formatında, hangi alanın neden hata verdiğini açıklayacak şekilde istemciye döndürür. Bu, API kullanan geliştiriciler için çok daha açıklayıcı bir hata yönetimidir.
Doğrulama Yöntemlerinin Karşılaştırılması
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Bean Validation (@Valid) | Temiz kod, standartlara uygun | Karmaşık iş mantığı için yetersiz kalabilir |
| Manuel Validator | Tam kontrol, karmaşık kurallar | Kod tekrarı, bakım zorluğu |
| Custom Annotations | Yeniden kullanılabilirlik | Yazım süresi daha uzun |
Özel Doğrulama Kuralları Oluşturma
Bazen standart anotasyonlar (örn: @Email) yeterli olmaz. Örneğin, sadece belirli bir alan adı (domain) ile biten e-postaları kabul etmek isteyebilirsiniz. Bunun için kendi anotasyonunuzu oluşturabilirsiniz.
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DomainValidator.class)
public @interface ValidDomain {
String message() default "Geçersiz e-posta domaini";
Class[] groups() default {};
Class
Validation Süreçlerinde Performans Optimizasyonu
Spring Boot uygulamalarında doğrulama işlemleri, her istekte (request) tetiklendiği için yüksek trafikli sistemlerde performans darboğazı oluşturabilir. Özellikle karmaşık nesne hiyerarşilerinde veya veritabanı sorgusu gerektiren özel validasyonlarda dikkatli olunmalıdır.
Performansı artırmak için şu stratejileri uygulayabilirsiniz:
- Doğrulama Grupları (Validation Groups): Tüm nesneyi değil, sadece ilgili işlem için gerekli alanları doğrulayın.
- Önbellekleme (Caching): Veritabanına giderek kontrol yapan özel validator sınıflarında, sonuçları
@Cacheable ile önbelleğe alarak veritabanı yükünü azaltın.
- Hızlı Başarısızlık (Fail-Fast): Hibernate Validator'ın varsayılan davranışını değiştirerek ilk hatada işlemin durmasını sağlayın.
// Fail-fast yapılandırması için Bean tanımı
@Configuration
public class ValidationConfig {
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
// İlk hatada doğrulamayı durdurur
factoryBean.getValidationPropertyMap().put("hibernate.validator.fail_fast", "true");
return factoryBean;
}
}
Validation Testleri ve Birim Test Stratejileri
Doğrulama kurallarınızın beklendiği gibi çalıştığından emin olmak için Validator arayüzünü doğrudan test sınıflarınızda kullanabilirsiniz. Bu, uygulamanın tamamını ayağa kaldırmadan (mocking yapmadan) hızlı geri bildirim almanızı sağlar.
Aşağıdaki örnek, bir UserDTO nesnesinin kısıtlamalarını nasıl test edebileceğinizi gösterir:
@ExtendWith(MockitoExtension.class)
class UserValidationTest {
private Validator validator;
@BeforeEach
void setup() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
void shouldReturnErrorWhenEmailIsInvalid() {
UserDTO user = new UserDTO("test", "gecersiz-email");
Set violations = validator.validate(user);
assertFalse(violations.isEmpty());
assertEquals("Geçersiz e-posta formatı", violations.iterator().next().getMessage());
}
}
İleri Seviye Hata Ayıklama (Debugging)
Doğrulama hatalarını ayıklarken, MethodArgumentNotValidException nesnesinin içindeki BindingResult içeriğini incelemek kritiktir. Eğer hata mesajlarınızın neden tetiklenmediğini bulamıyorsanız, ValidationMessages.properties dosyasının classpath üzerinde doğru konumlandırıldığından ve @Valid veya @Validated anotasyonlarının doğru katmanda (Controller metot parametresi) kullanıldığından emin olun.
İpucu: Eğer @Validated anotasyonunu bir sınıf seviyesinde kullanıyorsanız, Spring'in bu sınıfı bir Bean olarak yönettiğinden ve Proxy üzerinden çağrıldığından emin olun. Aksi takdirde doğrulama kuralları sessizce atlanacaktır.


Yorumlar (0)
Yorum Yaz