Spring Boot Bean Validation Uygulama Örneği
Spring Boot Dersleri‘ne devam ediyorum.
Bu yazıda Spring Boot Uygulamasında Java Bean Validation’un nasıl kullanıldığına ve bu validasyon sonucunda kullancıya gerekli uyarı mesajlarının nasılverildiriğine bakacağız.
Java Bean Validator’un ne olduğuna aşağıdaki yazıdan bakabilirsiniz.
İlgini Çekebilir: Java Bean Validation Annotation Nedir?Bir öğrenci bilgilerini kaydeden bir rest apimiz olacak ve öğrenci entitymizdeki alanlarımızın belirli bir validasyon kuralları koyacağız ve buradan çıkacak olan hata mesajlarını kullanıcıya göstereceğiz.
Uygulama
Uygulamamızdaki bağımlıklar şunlar olacaktır.
- Spring Boot Starter Validation
- Spring Boot Starter Web
- H2
- Lombok
- Spring Data JPA
Projemizde validasyon işlemlerini Starter Boot Starer Validation sağlayacaktır.
Maven projemizin bağımlılıkları;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Code language: HTML, XML (xml)
Student modelimizi oluşturalım.
@Data
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
@Size(min = 2, message = "Must be not null")
private String nameSurname;
@Max(value = 99999)
@Positive
private int studentNumber;
@NotBlank(message = "Must be not blank")
private String schoolName;
@Email(message = "Email should be valid")
private String email;
@Min(value = 18, message = "Cannot be younger than 18 years old.")
private int age;
@Pattern(regexp = "[0-9\\s]{12}")
private String phone;
}
Code language: CSS (css)
Entitymizi oluştururken kullandığımız validasyonlara dikkat edelim ve bu validasyonların isteğe göre message parametresine değer verebilmekteyiz.
- Pattern
- Min
- NotBlank
- NotNull
- Size
Şimdi repositorymizi oluşturalım.
public interface StudentRepository extends JpaRepository<Student,Long> {
}
Code language: PHP (php)
Servis katmanımızı oluşturalım H2 veritabanımıza kayıt edeceğimiz metotlarımızı yazalım. Bunun için ise StudentRepository kullanacağız.
@Service
public class StudentService {
@Autowired
StudentRepository studentRepository;
public void save(Student student){
studentRepository.save(student);
}
}
Code language: PHP (php)
Controllerimizi oluşturalım, controllerimizde rest api üzerinden erişim sağlanacak bir endpointimiz olacaktır.
@RestController
public class StudentController {
@Autowired
StudentService studentService;
@PostMapping("/save")
ResponseEntity<String> addStudent(@Valid @RequestBody Student student) {
studentService.save(student);
return ResponseEntity.ok("Student Saved");
}
}
Code language: CSS (css)
Controller’ımızın addStudent metodunda @Valid anotasyonu olduğuna dikkat edin. @Valid anotasyonu ekleyerek apimize gelen alanlara belirlediğimiz kriterlerin doğruluğu kontrol edilmektedir. Bu anotasyon ile birlikte iş alanlarımızda belirlediğimiz alanların istediğimiz kritere ve doğruluğa olduğu takdirde metotumuza girer aksi takdirde servsimiz hata verir.
İstek atalım.
Postman üzerinden gelen isteğe bakalım.
Api’yi kullanan kişiye sadece bu mesaj gitmektedir. Bizim yazmış olduğumuz mesajlar gitmiyor, ancak yazılımımızın konsol çıktısına baktığımızda hata mesajları gözükmektedir.
Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in org.springframework.http.ResponseEntity<java.lang.String> com.burakkutbay.springbootbeanvalidation.controller.StudentController.addStudent(com.burakkutbay.springbootbeanvalidation.model.Student) with 4 errors: [Field error in object 'student' on field 'schoolName': rejected value [null]; codes [NotBlank.student.schoolName,NotBlank.schoolName,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.schoolName,schoolName]; arguments []; default message [schoolName]]; default message [Must be not blank]] [Field error in object 'student' on field 'age': rejected value [0]; codes [Min.student.age,Min.age,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.age,age]; arguments []; default message [age],18]; default message [Cannot be younger than 18 years old.]] [Field error in object 'student' on field 'studentNumber': rejected value [0]; codes [Positive.student.studentNumber,Positive.studentNumber,Positive.int,Positive]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.studentNumber,studentNumber]; arguments []; default message [studentNumber]]; default message [must be greater than 0]] [Field error in object 'student' on field 'nameSurname': rejected value [null]; codes [NotNull.student.nameSurname,NotNull.nameSurname,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.nameSurname,nameSurname]; arguments []; default message [nameSurname]]; default message [must not be null]] ]
....
...
..
Code language: CSS (css)
Şeklinde uzayıp giden ve bizim valid mesajlarımızı içeren hata mesajlarınızı yazılım konsolunda görmekteyiz.
Peki neden api kullanıcımız bu mesajlarımızı göremiyor?
Yazılımlarımızda oluşan bu hataları handle ederek yakalacağız.
@ControllerAdvice Kullanımı
Controller Advice anotasyonu başlı başına ayrı bir konu olsa da kısaca bahsedelim. Spring uygulamalarımızın içerisinde oluşabilecek tüm hataları yakalamamıza olanak sağlayan bir anotasyondur. Bu anotasyon sayesinde uygulamalarımızda oluşan hataları handle ederek response’unu kontrol edebiliriz.
Bean validasyon uygulamamızın içerisinde oluşan hataların kullanıcıya gösterilmesi evresinde @ControllerAdvice‘dan yararlanarak oluşan tüm hataların ResponseEntity olarak response’da cevap olarak verilmesini sağlamaktayız.
@ControllerAdvice
public class ValidationHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) ->{
String fieldName = ((FieldError) error).getField();
String message = error.getDefaultMessage();
errors.put(fieldName, message);
});
return new ResponseEntity<Object>(errors, HttpStatus.BAD_REQUEST);
}
}
Code language: JavaScript (javascript)
Yukarıdaki kod bloğunda ise ResponseEntity’lerinden oluşabilecek tüm hataların yakalanıp hata mesajlarının cevap olarak geri döndürülmesini sağlıyoruz. Bu sayede ise bizim entitymizdeki yazdığımız hata mesajlarımız da kullanıcıya cevap olarak döndürülmesini sağlamış oluyoruz.
Tekrar istek atalım ve cevabına bakalım.
Bean validasyon üzerinde bulunan hata mesajlarımız da Controller Advice kullanarak göstermiş olduk.
No Comment! Be the first one.