솔솔

코드 품질을 높이는 리팩토링 여정, 한 달간의 기록 (Controller 입력 값 검증) 본문

내인생's 기록/도전2

코드 품질을 높이는 리팩토링 여정, 한 달간의 기록 (Controller 입력 값 검증)

솔솔하네 2025. 4. 4. 22:41
반응형

🤔 문제


다음으로 리팩토링 할 부분을 찾다가 Controller 부분에서 

발길이 멈췄다. (마우스로 이동이닌깐 손길인가??)

 

눈에 띄는 잘못된 어노테이션 사용이 있었던 것이다.

 

1️⃣ Controller에서 잘못 사용된 어노테이션 @Validated → @Valid

 

2️⃣ DTO에서 String 필드 값 검증 시 @NotEmpty 사용 문제

 

 

⚒️ Controller 입력 값 검증 리팩토링


1️⃣ Controller에서 잘못 사용된 어노테이션 @Validated → @Valid

POST 요청을 처리하는 Controller에서 입력값 검증을 위해 @Validated 어노테이션을 사용하고 있었다.

@PostMapping("/join")
  public ResponseEntity<String> join(@Validated @RequestBody EnterpriseJoinDTO enterpriseJoinDTO){
    return ResponseEntity.ok(enterpriseAuthFacade.join(enterpriseJoinDTO));
}

 

@Validated는 아래와 같이 springframework에 제공해주는 어노테이션이다.

import org.springframework.validation.annotation.Validated;

 

클래스나 인터페이스 단위로 유효성 검사를 할 때, 특히 Service 계층에서 AOP 기반 유효성 검사를 적용할 때 주로 사용된다.

 

하지만 위의 경우처럼,

Controller에서 클라이언트로부터 전달받은 DTO를 검증할 때는 @Validated 대신 @Valid를 사용해야 한다.

 

@Valid는 아래처럼 DTO를 메서드의 파라미터로 받을 때 사용하며, DTO 내부에 선언된 유효성 검증 어노테이션들(@NotBlank, @Size, 등등)을 정상적으로 작동하게 해준다.

@PostMapping("/join")
public ResponseEntity<String> join(@Valid @RequestBody EnterpriseJoinDTO enterpriseJoinDTO){
	return ResponseEntity.ok(enterpriseAuthFacade.join(enterpriseJoinDTO));
}

 

@ValidJakarta 에서 제공하는 기능이며, 아래와 같은 의존성이 필요하다:

// Gradle
implementation 'org.springframework.boot:spring-boot-starter-validation'

 

import jakarta.validation.Valid;

 

👉  정리하자면 Controller에서 입력값 검증 시에는 반드시 @Valid를 사용을해야 된다.

잘못된 어노테이션 사용은 DTO 내부의 유효성 검증이 무시되는 결과를 초래할 수 있기 때문에 

어노테이션의 올바른 사용방법을 숙지하고 각각 역할에 맡게 잘 사용해야 된다!!

 

 

2️⃣ DTO에서 String 필드 값 검증 시 @NotEmpty 사용 문제

입력 값 검증 시, @NotEmpty를 사용하여 String 필드를 검증하는 코드가 있었다.

@Getter
@AllArgsConstructor
@Builder
@Setter
public class EnterpriseJoinDTO {
  @NotEmpty(message = "entId 필드는 필수입니다.")
  private String entId;

  @NotEmpty(message = "regNum 필드는 필수입니다.")
  private String regNum;
}

 

@NotEmpty는 null과 빈 문자열("")을 막지만, 공백 문자열(" ")은 허용한다.

하지만 해당 필드들은 반드시 값이 들어가야하고 공백도 허용하지 않는다.

 

즉 @NotEmpty를 사용하여 String 필드를 검증했지만, 공백 문자열( " " )이 허용되는 문제가 있었던 것이다.

 

👉 그래서 이에 대한 해결방법은 @NotBlank로 변경하여 공백 문자열도 막는 것이다.

@Getter
@AllArgsConstructor
@Builder
@Setter
public class EnterpriseJoinDTO {
  @NotBlank(message = "entId 필드는 필수입니다.")
  private String entId;

  @NotBlank(message = "regNum 필드는 필수입니다.")
  private String regNum;
}

 

@NotBlank는 null과 빈 문자열("") 그리고 공백 문자열(" ")까지도 막아준다.

 

테스트 시 정상적으로 작동하는것을 볼 수 있다.