Spring Boot ile Validation Yöntemleri

Yağız Gazibaba
Kod Gemisi
Published in
5 min readApr 16, 2018
Image Source: javadevjournal

Merhaba, bu yazıda Spring Validation yöntemlerinden bahsedip uygulayacağız.

Neler kullanacağız:

Öncelikle Validation API nedir bununla başlayalım.

“Top level package of the Bean Validation API.”(Bkz: Package javax.validation.constraints )

1-Obje modellerimize annotation’lar yardımıyla constraintler koymamızı sağlar.

2-Custom constraintler yazmamızı sağlar(“lets you write custom constraints in an extensible way”)

3-Parametrelerimizi, metodlarımızın geri dönüş değerlerini ve constructorlarımızı validate etmemizi sağlar.

4-Constraint ihlalleri localized bir biçimde yapılabilir.

5-Java SE ile çalışabilir, JavaEE 6'dan sonrasında entegre olarak bulunur. Bean Validation 2.0 JavaEE 8'in bir parçasıdır.

(From : http://beanvalidation.org/)

— — — — — — — — — — — — — — — — — —

Bütün projelerde data’yı validate etmek büyük önem taşır. Bunun için Java’da validate etmemizi sağlayan, Java EE standardı olmuş Bean Validation(http://beanvalidation.org/1.1/spec/) bulunur. Annotation’lar yardımıyla ya da custom validation’lar ile verilere constraint’ler koyup validate edebiliriz. Üstte gördüğünüz gibi Javax Validation adında bir validation package’ımız var ve bu package’ımızın içinde Bean Validation API’miz var.(Detaylı bilgiye burdan ulaşabilirsiniz: JSR 380)

Ve tabiki Spring Framework’te Bean Validation’u destekliyor (https://spring.io/guides/gs/validating-form-input/)

1. Constraint Annotations

1.1. Customer adlı bir model oluşturalım.

package com.validationExample.validationexample.model;import lombok.Data;import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
/**
* Created on March, 2018
*
*
@author yagiz
*/
@Data
public class Customer {
//Bos birakilamaz Annotation'u
@NotEmpty(message = "Isim bos bırakılamaz.")
private String firstName;
//Bos birakilamaz Annotationu
@NotEmpty(message = "Soyisim bos birakilamaz.")
private String surname;
//Min value Annotation'u
@Min(value = 18, message = "18 yasindan kucuk musteri olamaz.")
private int age;
//Mail check Annotation'u
@Email(message = "Hatali email")
private String email;
//Regex Annotation'u
@Pattern(regexp ="[0-9\\s]{12}")
private String phone;
}

Üstte gördüğünüz gibi @NotEmpty, @Min, @Email, @Pattern constraint’lerini kullandık. @NotEmpty adından anlaşılacağı gibi boş bırakılamaz anlamına geliyor. @Min gelen integer’ın value parametre’siyle 18, en az 18 olabileceği constraint’ini sağlıyor. @Email gelen mail verisinin e-mail formatında olduğunu kontrol ediyor ve böylece @Pattern ile regex patternler yazıp kontrol edebiliyoruz. (Customer class’ındaki @Data annotation’u kafanızı karıştırmasın, lombok adlı plugini kullandığım için koydum, onu kullanmayıp getter setter yazabilirsiniz.)

1.2. Customer Controller

Customer controller’ı oluşturalım Get ve Post metodlarını yazalım.

package com.validationExample.validationExample;import com.validationExample.validationExample.model.Customer;
import lombok.extern.java.Log;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import javax.validation.Valid;/**
* Created on March, 2018
*
*
@author yagiz
*/
@Controller
@Log
public class CustomerController {
@GetMapping("/")
public String getCustomerCreatePage(Model model){
model.addAttribute("customer", new Customer());
return "addCustomer";
}
@PostMapping("/")
public String createCustomer(@Valid @ModelAttribute("customer") Customer customer, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
return "addCustomer";
}
log.info("Customer Created");
return "addCustomer";
}
}

Get Method’umuzda model objesi ile view’ımıza customer modeli ekliyoruz ve addCustomer view’ımızı return ediyoruz.

Post metodumuzda ise @Valid parametresi ile customer model attribute’umuzu validate etmesini söylüyoruz.

1.3. View’ımızı Oluşturalım

<!DOCTYPE html>
<html th:lang="${#locale.language}"
xmlns:th="http://www.thymeleaf.org"
>
<head>
<title>Items</title>
<title>Spring Validation Example </title>
</head>
<body>
<form th:action="@{/}" th:object="${customer}" th:method="post">
<div>
<label>Isim</label>
<input type="text" th:field="*{firstName}"/>
<div th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}"></div>
</div>
<div>
<label>Soyisim</label>
<input type="text" th:field="*{surname}"/>
<div th:if="${#fields.hasErrors('surname')}" th:errors="*{surname}"></div>
</div>
<div>
<label>Yaş</label>
<input type="text" th:field="*{age}"/>
<div th:if="${#fields.hasErrors('age')}" th:errors="*{age}" value=""></div>
</div>
<div>
<label>Email</label>
<input type="text" th:field="*{email}"/>
<div th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></div>
</div>
<div>
<label>Telefon</label>
<input type="text" th:field="*{phone}"/>
<div th:if="${#fields.hasErrors('phone')}" th:errors="*{phone}"></div>
</div>
<div>
<button type="submit">Ekle</button>
</div>
</form>
</body>
</html>

View’ımızı oluşturduk.

th:if="${#fields.hasErrors('phone')}

ile error olup olmadığını kontrol edip varsa bu tag’i render et dedik.

th:errors="*{phone}"

Hangi field’ın error message’ı olduğunu söyledik.

Hadi Deneyelim!

Verilerimizi yazıp submit edelim ve sonucu görelim:

2 . Custom Validation

Annotation’ların yeterli olmadığı yerlerde custom validation kullanabiliriz; bunun için bir adet CustomValidator adında bir class oluşturaracağız.

package com.validationExample.validationExample.validation;import com.validationExample.validationExample.model.Customer;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/**
* Created on March, 2018
*
*
@author yagiz
*/
@Component
public class CustomerValidator implements Validator{
@Override
public boolean supports(Class<?> clazz) {
return Customer.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
Customer customer = (Customer) target;
if (customer.getFirstName().equalsIgnoreCase("noname")) {
errors.rejectValue("firstName", null, "First Name can not be NONAME");
}
}
}

Gördüğünüz gibi bir CustomerValidator adlı class’ım var bu class Validator interface’ini implement ediyor, biz de supports metodumuzun içini dolduruyoruz. Bu metodu gelen class’ın beklediğimiz type’ta olduğundan emin olmak için kullanıyoruz. Validate metodumuzda ise; adından da anlaşılacağı gibi validation kontrollerimizi yapıyoruz. customer.getFirstName ile ismi alıp noname ile karşılaştırıyoruz. Eğer eşitse rejectValue ile validation’ı reject edip hangi field’ımızın reject edildiğini ve error mesajını yazıyoruz.

Şimdi controller’ımızda CustomerValidation validator’ımızı bind etmemiz gerek.

package com.validationExample.validationExample;import com.validationExample.validationExample.model.Customer;
import com.validationExample.validationExample.validation.CustomerValidator;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import javax.validation.Valid;/**
* Created on March, 2018
*
*
@author yagiz
*/
@Controller
@Log
public class CustomerController {
@Autowired
CustomerValidator customerValidator;
@InitBinder
protected void initBinder(final WebDataBinder binder){
binder.addValidators(customerValidator);
}
@GetMapping("/")
public String getCustomerCreatePage(Model model){
model.addAttribute("customer", new Customer());
return "addCustomer";
}
@PostMapping("/")
public String createCustomer(@Valid @ModelAttribute("customer") Customer customer, BindingResult bindingResult){
if (bindingResult.hasErrors()){
return "addCustomer";
}
log.info("Customer Created");
return "addCustomer";
}
}

CustomerValidator’ımızı enjekte ettik ve @InitBinder ile validator’ımızı bind ettik. Şimdi bakalım validate metodunda yazdığımız gibi İsim yerine noname yazıldığında hata verecek mi?

Hadi Deneyelim:

İsim kısmına noname yazıp submit edelim.

İsim kısmına Noname yazıp submit ettikten sonra error mesajı aldık.

Validation anlatımını burada bitiriyorum. Sormak veya önermek istediğiniz konular için yorum kısmına yazmaya çekinmeyin.

--

--