반응형
Validation
클라이언트의 데이터는 조작이 쉽고, 모든 데이터가 정상적인 방식으로 들어오지 않을 가능성도 있기 때문에
Client Side뿐만 아니라 Server Side에서도 데이터 유효성 검사를 할 필요가 있다.
=>Spring boot starter validation 활용
사용 방법
1. 의존성 추가
2. Controller의 유효성 검사 적용 Request 객체 앞에 @Validated 어노테이션 추가
3. Request를 핸들링 할 객체 정의 시 @Validated 어노테이션을 통해 필요한 유효성 검사 적용
Validation Test
pom.xml 에 라이브러리 추가
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
UserDTO
@NotNull : null 허용하지 않음. "", " " 허용
@NotBlank : null, "", " " 모두 허용하지 않음
@Size : (min= , max=) 길이 제한, @Min, @Max로도 표현 가능
@Past : 현재보다 과거
@Future : 현재보다 미래
public class UserDTO {
private int no;
@NotNull(message = "아이디는 반드시 입력되어야 합니다.")
@NotBlank(message = "아이디는 공백일 수 없습니다.")
private String id;
private String pwd;
@NotNull(message = "이름은 반드시 입력되어야 합니다.")
@Size(min=2, message="이름은 2글자 이상 입력해야 합니다.")
private String name;
@Past
private java.util.Date enrollDate;
public UserDTO() {}
public UserDTO(int no, String id, String pwd, String name, Date enrollDate) {
super();
this.no = no;
this.id = id;
this.pwd = pwd;
this.name = name;
this.enrollDate = enrollDate;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public java.util.Date getEnrollDate() {
return enrollDate;
}
public void setEnrollDate(java.util.Date enrollDate) {
this.enrollDate = enrollDate;
}
@Override
public String toString() {
return "UserDTO [no=" + no + ", id=" + id + ", pwd=" + pwd + ", name=" + name + ", enrollDate=" + enrollDate
+ "]";
}
}
ErrorResponse
public class ErrorResponse {
private String code;
private String description;
private String detail;
public ErrorResponse(String code, String description, String detail) {
super();
this.code = code;
this.description = description;
this.detail = detail;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
@Override
public String toString() {
return "ErrorResponse [code=" + code + ", description=" + description + ", detail=" + detail + "]";
}
}
ExceptionController
@ControllerAdvice : 컨트롤러를 보조해주는 기능을 제공한다는 것을 명시 전역 예외처리를 등록할 수 있다.
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserResistException(UserNotFoundException e){
String code = "ERROR_CODE_00000";
String description = "회원 정보 조회 실패";
String detail = e.getMessage();
return new ResponseEntity<>(new ErrorResponse(code, description, detail), HttpStatus.NOT_FOUND);
}
/* 유효성이 통과되지 못하는 오류가 발생하면 동작하는 메소드*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> methodValidException(MethodArgumentNotValidException e){
String code ="";
String description = "";
String detail = "";
/* 에러가 있다면 */
if(e.getBindingResult().hasErrors()) {
detail = e.getBindingResult().getFieldError().getDefaultMessage();
String bindResultCode = e.getBindingResult().getFieldError().getCode();
System.out.println(bindResultCode);
switch(bindResultCode) {
case "NotNull":
code = "ERROR_CODE_00001";
description = "필수 값이 누락되었습니다.";
case "NotBlank":
code = "ERROR_CODE_00002";
description = "필수 값이 공백으로 처리되었습니다.";
case "Size":
code = "ERROR_CODE_00003";
description = "알맞은 크기의 값이 입력되지 않았습니다.";
}
}
ErrorResponse errorResponse = new ErrorResponse(code, description, detail);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
반응형
UserNotFoundException
public class UserNotFoundException extends Exception {
public UserNotFoundException(String msg) {
super(msg); //최종적으로 Exception객체 쪽에 저장되게 만든다
}
}
ValidTestController
import java.net.URI;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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("/valid")
public class ValidTestController {
/*1. 유저조회- Exception Test*/
@GetMapping("/users/{userNo}")
public ResponseEntity<?> findUserByNo() throws UserNotFoundException{
boolean check = true;
if(check) {
throw new UserNotFoundException("회원 정보를 찾을 수 없습니다.");
}
return ResponseEntity.ok().build();
}
/* 2. 유저 등록 - valid Test*/
@PostMapping("/users")
public ResponseEntity<?> registUser(@Validated @RequestBody UserDTO user){
System.out.println(user);
return ResponseEntity
.created(URI.create("/valid/users/" + "userNo"))
.build();
}
POSTMAN - 유저 조회 (Exception Test)
POSTMAN - 유저 등록 (Valid Test)
반응형
'프로그래밍 > Spring & Spring boot' 카테고리의 다른 글
[Spring boot] RESTAPI _ 05 Swagger (0) | 2022.11.03 |
---|---|
[Spring boot] RESTAPI_05 Hateoas (0) | 2022.11.03 |
[Springboot] RESTAPI_03 ResponseEntity (0) | 2022.11.03 |
[Spring boot] RESTAPI_02 Response (0) | 2022.11.03 |
[Spring boot ] REST API - 01 REST API & POSTMAN (0) | 2022.11.02 |