*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성
- Windows11(윈도우 11) 환경
- 자바 JDK 17 버전 설치 https://yungenie.tistory.com/11
[Java] 차근차근 Java 설치하기 (JDK17, Window 11)
자바 개발 도구 설치 방법에 대해서 알아보겠습니다. Java17은 LTS(Long Term Support : 장기 지원) 릴리즈로 1년 후까지 기술 지원 및 버그를 개선한 서비스를 제공받을 수 있습니다. 업데이트 버전을 꾸
yungenie.tistory.com
- 스프링 부트 4.31.0 사용 - STS(Spring Tool Suite) 설치(Spring Tools for Eclipse - https://spring.io/tools)
=> https://priming.tistory.com/147 참고
[Windows] Spring Tool Suite 4(STS 4) 다운로드 및 설치
STS란?Spring Tool Suite(STS)는 스프링 프로젝트를 생성하고, 개발할 수 있게 해주는 도구입니다. STS 설치 과정에 대해 설명드리겠습니다. 설치 파일 다운로드STS 공식 사이트에서 설치 파일을 다운로
priming.tistory.com

- MySQL Community Server 8.0.42 설치 https://dev.mysql.com/downloads/mysql/
MySQL :: Download MySQL Community Server
Select Version: 9.3.0 Innovation 8.4.5 LTS 8.0.42 Select Operating System: Select Operating System… Microsoft Windows Ubuntu Linux Debian Linux SUSE Linux Enterprise Server Red Hat Enterprise Linux / Oracle Linux Fedora Linux - Generic Oracle Solaris mac
dev.mysql.com

- Gradle
**STS에서 Gradle 프로젝트 생성한 과정



*** 함께 보면 좋은 글
스프링 부트 핵심 가이드(장정우 지음) - 스프링 부트 개요
1. 스프링 프레임워크자바(Java) 기반 애플리케이션 프레임워크로, 엔터프라이즈급(기업 환경 대상 개발) 애플리케이션을 위한 다양한 기능 제공-> 오픈소스 경량급 애플리케이션 프레임워크로
keep-programming-study.tistory.com
스프링 부트 핵심 가이드(장정우 지음) - 개발에 앞서 알면 좋은 기초 지식
1. 서버 간 통신마이크로서비스 아키텍처에서 한 서버가 다른 서버에 통신을 요청하는 것을 의미-> 한 대는 서버/다른 한 대는 클라이언트가 됨 가장 많이 사용되는 방식은 HTTP/HTTPS 방식(TCP/IP, SOA
keep-programming-study.tistory.com
스프링 부트 핵심 가이드(장정우 지음) - REST API 명세를 문서화하는 방법(Swagger), 로깅 라이브러리
*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성 Windows11(윈도우 11) 환경자바 JDK 17 버전 설치 https://yungenie.tistory.com/11 [Java] 차근차근 Java 설치하기 (JDK17, Window 11)자바 개발 도구 설치 방법
keep-programming-study.tistory.com
1. 일반적인 애플리케이션 유효성 검사의 문제점: 복잡하고 가독성이 떨어지는 코드
- 계층별로 진행하는 유효성 검사는 데이터 검증 로직이 각 클래스별로 분산되어 잇어 관리가 어려움
- 데이터 검증 로직에 중복이 많아 여러 곳에 유사한 기능의 코드가 존재할 수 있음
- 검증해야 할 값이 많다면 검증 코드가 길어짐
2. Bean Validation: 자바 진영에서 2009년부터 데이터 유효성 검사 프레임워크 제공
- 어노테이션을 통해 다양한 데이터를 검증하는 기능을 제공하여, 코드의 간결함을 유지
- 유효성 검사를 위한 로직을 DTO같은 도메인 모델과 묶어서,
각 계층에서 사용하면서 검증 자체를 도메인 모델에 얹는 방식으로 수행
*Hibernate Validator
- Bean Validation 명세의 구현체가 Hibernate Validator
- 스프링부트에서는 이를 유효성 검사 표준으로 채택하여 사용함
- JSR-303 명세의 구현체로서 도메인 모델에서 어노테이션을 통한 필드값 검증을 도움
-> JSR-303: 자바에서 객체의 유효성을 검사하기 위한 표준 명세이자 Bean Validation 1.0을 정의한 스펙,
주로 @Valid와 다양한 제약 애노테이션을 통해 객체 필드의 유효성을 자동으로 검증
3. 스프링 부트에서의 유효성 검사 예시
1) build.gradle에 의존성 추가 및 저장한 후 우클릭 -> Gradle -> Refresh Gradle Project 선택
dependencies {
... 생략 ...
// 유효성 검사
// spring-boot-starter-web에는 JSR-303 기반 유효성 검사 기능이 일부 포함되어 있지만
// 구현체인 Hibernate Validator는 spring-boot-starter-validation에 포함돼 있으므로, 유효성 검사를 제대로 사용하려면 이 의존성을 명시적으로 추가
implementation 'org.springframework.boot:spring-boot-starter-validation'
}

2) 스프링 부트의 유효성 검사 이해
- 각 계층으로 넘어오는 시점에 해당 데이터에 대한 유효성 검사를 실시
- 스프링 부트 프로젝트에서는 계층 간 데이터 전송에 대체로 DTO 객체를 활용하고 있으며,
따라서 다음과 같이 유효성 검사를 DTO 객체를 대상으로 수행하는 것이 일반적

3) DTO와 컨트롤러 생성
(1) DTO 생성
package com.example.demo.jpa.data.dto;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data // Getter, Setter, equals(), hashCode(), toString() 메서드를 자동 생성해주는 종합 패키지 애노테이션
@NoArgsConstructor // 파라미터가 없는 기본 생성자 자동 생성
@AllArgsConstructor // 모든 필드를 파라미터로 받는 생성자 자동 생성
@ToString // toString() 메서드를 자동 생성 (필드 값을 문자열로 표현)
@Builder // 빌더 패턴을 적용해 객체를 유연하게 생성할 수 있도록 지원
public class ValidRequestDto {
// name 필드는 null이거나 공백이면 안 됨 (빈 문자열도 허용하지 않음)
@NotBlank
String name;
// email 필드는 이메일 형식이어야 함 (예: user@example.com)
@Email
String email;
// 휴대폰 번호는 특정 패턴을 따라야 하므로 정규표현식 사용 (010-1234-5678 또는 011.234.5678 형식)
@Pattern(regexp = "01(?:0|1|[6-9]).[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$")
String phoneNumber;
// age는 최소 20 이상, 최대 40 이하의 값이어야 함
@Min(value = 20)
@Max(value = 40)
int age;
// description은 길이가 0 이상 40 이하의 문자열이어야 함
@Size(min = 0, max = 40)
String description;
// count는 반드시 양수여야 함 (0은 허용되지 않음)
@Positive
int count;
// booleanCheck는 반드시 true여야 함 (false이면 유효성 검사 실패)
@AssertTrue
boolean booleanCheck;
}
(2) 컨트롤러 생성
- 전에 STS4에서 @RequestBody가 죽어도 먹히지 않는 지옥을 경험했기 때문에,
책 내용과 다르게 @RequestParam 방식의 코드 작성
-> 실제로는 보안에 좋지 않기 때문에 IntelliJ를 써서 @RequestBody로 받는게 맞습니다
package com.example.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RestController // REST API 컨트롤러로 동작함을 나타냄 (@Controller + @ResponseBody)
@RequestMapping("/validation") // 이 컨트롤러의 기본 URL 경로를 "/validation"으로 설정
public class ValidationController {
// SLF4J 로깅 인터페이스를 사용하여 로그를 출력할 수 있도록 Logger 객체 생성
private final Logger LOGGER = LoggerFactory.getLogger(ValidationController.class);
// POST 요청을 "/validation/valid" 경로로 매핑
@PostMapping("/valid")
public ResponseEntity<String> checkValidationByValid(
// 각 파라미터에 유효성 검사 애노테이션을 직접 적용
@RequestParam("name") @NotBlank String name,
@RequestParam("email") @Email String email,
@RequestParam("phoneNumber") @Pattern(regexp = "01(?:0|1|[6-9]).[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$") String phoneNumber,
@RequestParam("age") @Min(20) @Max(40) int age,
@RequestParam("description") @Size(min = 0, max = 40) String description,
@RequestParam("count") @Positive int count,
@RequestParam("booleanCheck") @AssertTrue boolean booleanCheck
) {
// 요청 파라미터를 로그로 출력
LOGGER.info("name={}, email={}, phoneNumber={}, age={}, description={}, count={}, booleanCheck={}",
name, email, phoneNumber, age, description, count, booleanCheck);
// 응답 본문으로 파라미터 내용을 문자열로 반환
String response = String.format("name=%s, email=%s, phoneNumber=%s, age=%d, description=%s, count=%d, booleanCheck=%b",
name, email, phoneNumber, age, description, count, booleanCheck);
return ResponseEntity.status(HttpStatus.OK).body(response);
}
}
(3) 스프링부트 서버 실행 후 swagger에 접속해서 확인
- 스프링부트 서버 실행 시 오류 발생! DBC 드라이버가 데이터베이스 서버로부터 응답을 받지 못했으므로 윈도우의 '서비스'에서 MySQL8을 우클릭해서 '시작' 눌러서 해결
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2025-10-24 15:50:42.258 [main] WARN o.h.e.j.e.i.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata
org.hibernate.exception.JDBCConnectionException: unable to obtain isolated JDBC connection [Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.] [n/a]

- http://localhost:8080/swagger-ui/index.html에 접속하여 동작 확인



(4) 하나의 값이라도 유효성 검사에 맞지 않는 값을 입력하면 400 에러 발생
-> 예외 처리를 하지 않았으므로, 클라이언트는 어디서 에러가 발생했는지 알 수 없음

