본문 바로가기

프로그래밍/Spring Boot

Spring Boot_유효성 검사(Validation)

반응형

유효성 검사 (Validation)

: 올바르지 않은 데이터를 걸러내고 보안을 유지하기 위해 유효성을 검사하기 위해 사용한다.

ex) 자바에서는 null값에 대해서 접근하려고 할 때 NullPointException이 발생하기 때문에

이러한 부분을 방지하기 위해 미리 검증하는 과정을 Validation이라고 한다.

 

POST 방식일 때와 GET방식일 때의 유효성 검사 사용방법은 약간 다르다. 

POST 방식일 땐 매개변수에 반드시 @Valid를 선언해주어야 하고, 

GET 방식일 땐 클래스에 반드시 @Validated를 선언해주어야 한다.

 

Validation 어노테이션

@Size 문자 길이 측정
@NotNull null 불가
@NotEmpty null, "" 불가
@NotBlank null, "", " " 불가
@Past 과거 날짜
@PastOrPresent 오늘이거나 과거 날짜
@Futere 미래 날짜
@FuterOrPresent 오늘이거나 미래 날짜
@Pattern 정규식 적용
@Max 최대값
@Min 최소값
@AssertTrue / False 별도 Logic 적용
@Valid 해당 object validation 실행

 

User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Data //getter, setter, toString 자동으로 만들어줌
@NoArgsConstructor
@AllArgsConstructor // 생성자 
@Builder // 빌더 패턴
public class User {
    
    private String name;
    @Min(10)
    private int age;
    @Email(message = "이메일 형식으로 입력해주세요.")
    private String eamil;
    private String phoneNumber;
    
}
cs

 

ApiController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
@RestController
@RequestMapping("/api")
public class ApiController {
    
    // http://localhost:8080/api/user
    // 예전 유효성 검사 방식
    @PostMapping("/user")
    public ResponseEntity<User> user(@RequestBody User user) {
 
        // 스프링 부트의 요청시 데이터 기본 파싱 전략은 key - value 구조
        // dto <-- object mapper 동작을 해서 자동 파싱 처리해줌.
        if(user.getAge() < 1 || user.getAge() > 100) {
            // 잘못된 입력값일 시 
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(user);
        }
        
        // 빌더 패턴으로 값 넣기
        User user = User.builder()
                        .name("티모")
                        .age(0)
                        .email("asdf@naver.com")
                        .phoneNumber("010-1234-5678")
                        .build();
                        
        return ResponseEntity.ok(user);
    }
    
    // http://localhost:8080/api/user2
    @PostMapping("/user2")
    public ResponseEntity<User> user2(@Valid @RequestBody User user) {
        System.out.println(user);
        return ResponseEntity.ok(user);
    }
    
    // http://localhost:8080/api/user3
    @PostMapping("/user3")
    public ResponseEntity<?> user3(@Valid @RequestBody User user, BindingResult bindingResult) {
        
        // BindingResult 클래스는 @Valid에 대한 결과값을 가지고 있다.
        if(bindingResult.hasErrors()) {
            StringBuilder sb = new StringBuilder();
            
            bindingResult.getAllErrors().forEach(error -> {
                sb.append("field : " + error.getCode());
                sb.append("\n");
                sb.append("message : " + error.getDefaultMessage());
                sb.append("\n");
            });
            
            // 에러 발생시 반환
            // .body("에러발생")이면 에러 발생시 String 에러발생 반환
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(sb.toString());
        }
        
        //정상 처리
        return ResponseEntity.ok(user);
    }
}
cs

 

 

UserController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@RestController 
@Validated // !!!!!!! GET 방식일 때 반드시 선언해주어야 유효성 검사를 시작함 
public class UserController {
    
    // GET방식일 때 파라미터 앞에 어떤 유효성을 검사할지 지정해주어야 한다.
    
    // http://localhost:8080/user?name=찡구&age=3
    @GetMapping("/user")
    public User user(@Size(min = 2) @RequestParam String name, 
        @NotNull @Min(1) @RequestParam Integer age) {
        
        User user = new User();
        user.setName(name);
        user.setAge(age);
        return user;
    }
    
    // http://localhost:8080/user2?name=찡구&age=12
    // @Validated, @Valid 둘 다 됨.
    // @Valid <-- object mapper 통해서 파싱 처리
    @GetMapping("/user2")
    public User user2(@Valid User user) {
        return user;
    }
    
}
cs

→ @Valid라고 명시하면 dto에 있는 것들의 유효성을 검사하고, 

매개변수에 유효성을 검사를 명시하면 해당 매핑만 유효성 검사를 함.

 

 

파싱 결과

→ BindingResult가 @Valid에 대한 결과값을 가지고 있기 때문에 

bindingResult.getAllErrors() 메서드를 통해 .getCode()와 .getDefaultMessage()를 찍어줄 수 있다.

반응형