Validation 이란 프로그래밍에 있어 가장 필요한 부분,
특히 Java에서는 null 값에 대해 접근 하려고 할 때 null pointer exception이 발생 함으로 이러한 부분을 방지 하기 위해 미리 검증을 하는 과정을 말한다.
ex) 정상 logic 예제
public void run(String account, Spring pw, ing age){
if(account == null || pw == null){
return
}
if(age == 0){
return
}
}
검증해야 할 값이 많은 경우 코드의 길이가 길어진다.
구현에 따라서 달라 질 수 있지만 Service Logic 과의 분리가 필요하다.
흩어져 있는 경우 어디에서 검증을 하는지 알기 어려우며 재사용의 한계가 있다.
구현에 따라 달라질 수 있지만 검증 Logic이 변경 되는 경우 테스트 코드등 참조하는 클래스에서 Logic이 변경되어야 하는 부분이 발생 할 수 있다.
build.gradle - dependencies (validation)추가
plugins {
id 'org.springframework.boot' version '2.7.2'
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
Validation1Application.java
package com.example.validation.controller;
import java.lang.reflect.Field;
import javax.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.validation.dto.User;
import ch.qos.logback.core.recovery.ResilientSyslogOutputStream;
@RestController
@RequestMapping("/api")
public class ApiController {
// 1. 요청 유효성 검사를 하지 않은 경우
//@PostMapping("/user")
//public User user(@RequestBody User user) {
//System.out.println(user);
// User [name=ila, age=20, email=hyerihello@gmail.com, phoneNumber=22222]
//return user;
/* return {
"name": "ila",
"age": 20,
"email": "hyerihello@gmail.com",
"phoneNumber": "22222" } */
// 2. 기존 유효성 검사
@PostMapping("/user")
public ResponseEntity user(@RequestBody User user) {
System.out.println(user);
if(user.getAge() > 90) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(user);
}
return ResponseEntity.ok(user);
}
// 3. Validation 으로 유효성 검사
@PostMapping("/user2")
public ResponseEntity user2(@Valid @RequestBody User user) {
System.out.println(user);
if(user.getAge() > 90) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(user);
}
return ResponseEntity.ok(user);
}
// 4.validation 결과 파라미터를 받을 수 있는 BindingResult
@PostMapping("/user3")
public ResponseEntity user3(@Valid @RequestBody User user, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
StringBuilder sb = new StringBuilder();
bindingResult.getAllErrors().forEach(objectError -> {
FieldError field = (FieldError) objectError;
String message = objectError.getDefaultMessage();
System.out.println("field : " + field.getField());
System.out.println("message : " + message);
sb.append("field : " + field.getField() + "\n");
sb.append("message : " + message);
});
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(sb.toString());
}
return ResponseEntity.ok(user);
}
}
//System.out.println(user);
//if(user.getAge() > 90) {
// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(user);
//}
User.java
package com.example.validation.dto;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
public class User {
@NotBlank
private String name;
@Min(value = 0)
@Max(value = 90)
private int age;
@Email
private String email;
@Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$", message = "핸드폰 번호 양식이 맞지 않습니다.")
private String phoneNumber;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", email=" + email + ", phoneNumber=" + phoneNumber + "]";
}
}
validation default message
validation message 사용