
위와 같은 코드에서는,
인자가 3개밖에 없으니 코드가 짧지만
인자가 늘어나면 늘어날수록 코드(validation)가 길어지고 정상적인 로직을 짜는데 문제가 생길 수 있다.
또 잘못 작성하면 에러가 난다.

Validation은 변경되면 안된다!
그리고 잘 처리하기 위해 스프링에서 일관되게 제공하기 위해
어노테이션으로 제공한다
변수에다가 붙이면 된다

요청을 받을 것이기 때문에
cotroller 패키지 만들고 ValidationApplication.java만듦
<java />
package com.example.validation.controller;
import com.example.validation.dto.User;
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;
@RestController
@RequestMapping("/api")
public class ApiController {
@PostMapping("/user")
public Object user(@RequestBody User user){
System.out.println(user);
return user;
}
}
dto의 User도 만듦
<code />
package com.example.validation.dto;
public class User {
private String name;
private int age;
private String email;
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 + '\'' +
'}';
}
}


email과 phoneNumber에 이상한 형식이 들어가도 정상적인 Response 200이 나온다..
ApiController의 내용을 바꿔보자
<code />
package com.example.validation.controller;
import com.example.validation.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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;
@RestController
@RequestMapping("/api")
public class ApiController {
@PostMapping("/user")
public ResponseEntity user(@RequestBody User user) {
if (user.getAge() >= 90) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(user);
}
return ResponseEntity.ok(user);
}
}

100살 보내니까 에러가 난다!
하지만 방금처럼 코드를 짜면,
인자가 늘어날때마다 코드가 길어지니까
Validation이 꼭 필요한 것이다.
User.java
<java />
import javax.validation.constraints.Email;
public class User {
private String name;
private int age;
@Email //<--어노테이션 붙여줌
private String email;
private String phoneNumber;
User 내에 있는 변수에 Valid 어노테이션을 붙였으니,
아래 코드의 User에도 @Valid를 붙여줘야 한다.
<java />
package com.example.validation.controller;
import com.example.validation.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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 javax.validation.Valid;
@RestController
@RequestMapping("/api")
public class ApiController {
@PostMapping("/user")
public ResponseEntity user(@Valid @RequestBody User user) {
if (user.getAge() >= 90) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(user);
}
return ResponseEntity.ok(user);
}
}
@Valid가 붙은 객체는 그 안으로 들어가서 어노테이션(@Email)이 붙었는지 안 붙었는지 검사하기 때문


제대로 다시 보내면 성공!

핸드폰 번호에 대시(-)를 넣거나 안넣을 수도 있으니,
정규식을 활용해보자
<java />
"^\\d{2,3}-\\d{3,4}-\\d{4}$"
<code />
package com.example.validation.dto;
import javax.validation.constraints.Email;
import javax.validation.constraints.Pattern;
public class User {
private String name;
private int age;
@Email
private String email;
@Pattern(regexp="^\\d{2,3}-\\d{3,4}-\\d{4}$")
private String phoneNumber;
검색을 통해 다양한 정규식으로 통제해보자!
지금처럼 body를 보내면 바로 error가 나는 것이 아니라,
Valid에 오류가 나면 bindingResult라는 곳으로 값을 보내줄 수 있다.
bindingResult라는 객체를 통해 새로운 변환값을 받을 수 있다.
bindingResult가 없다면 예외처리로 가능!(아직 안배움)
<java />
package com.example.validation.controller;
import com.example.validation.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
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 javax.validation.Valid;
@RestController
@RequestMapping("/api")
public class ApiController {
@PostMapping("/user")
public ResponseEntity user(@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);
});
}
return ResponseEntity.ok(user);
}
}

message의 양식을 바꿔보자
<code />
package com.example.validation.dto;
import javax.validation.constraints.Email;
import javax.validation.constraints.Pattern;
public class User {
private String name;
private int age;
@Email
private String email;
@Pattern(regexp="^\\d{2,3}-\\d{3,4}-\\d{4}$", message="핸드폰 번호의 양식과 맞지 않습니다. 01x-xxx(x)-xxxx")
private String phoneNumber;

메세지를 바로 추가시키는 방법
<code />
package com.example.validation.controller;
import com.example.validation.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
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 javax.validation.Valid;
@RestController
@RequestMapping("/api")
public class ApiController {
@PostMapping("/user")
public ResponseEntity user(@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);
sb.append("field : "+field.getField());
sb.append("message : "+message);
});
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(sb.toString());
}
return ResponseEntity.ok(user);
}
}

이 API를 사용하는 사람이
응답만 보더라도 휴대폰 번호에 틀린 값을 잘못 넣었다는 것을 알 수 있다.
<code />
package com.example.validation.controller;
import com.example.validation.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
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 javax.validation.Valid;
@RestController
@RequestMapping("/api")
public class ApiController {
@PostMapping("/user")
public ResponseEntity user(@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);
sb.append("field : "+field.getField());
sb.append("message : "+message);
});
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(sb.toString());
}
//위에서 검증이 아주 잘 되었다면
//실질적으로 여기에 Logic을 짜면 된다
return ResponseEntity.ok(user);
}
}
여러가지 넣어봤다
<code />
package com.example.validation.dto;
import javax.validation.constraints.*;
public class User {
@NotBlank
private String name;
@Max(value=90, message="valid 어노테이션에는 어느 곳에나 메세지를 넣을 수 있습니다")
private int age;
컨트롤러 단에서 Validation을 사용하는 방법을 알아보았다!
변수 위에 annotation을 붙여주고,
컨트롤러에서 객체를 검사하고 싶은 부분에는 @Valid를 붙여주면 된다~
'Spring' 카테고리의 다른 글
Exception 처리 (0) | 2022.06.06 |
---|---|
Custom Validation (0) | 2022.06.05 |
Object Mapper 활용 - json 값 바꾸기 (0) | 2022.05.30 |
error: unmappable character (0x80) for encoding x-windows-949 오류 해결 (1) | 2022.05.29 |
스프링의 핵심 IOC & DI & AOP(활용) (0) | 2022.05.22 |