*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성
- 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. 서버 간 통신마이크로서비스 아키텍처에서 한 서버가 다른 서버에 통신을 요청하는 것을 의미-> 한 대는 서버/다른 한 대는 클라이언트가 됨 가장 많이 사용되는 방식은 HTTP/HTTPS 방식(TCP/IP, SOA
keep-programming-study.tistory.com
스프링 부트 핵심 가이드(장정우 지음) - Gradle 기초, API를 작성하는 다양한 방법
*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성 Windows11(윈도우 11) 환경자바 JDK 17 버전 설치 https://yungenie.tistory.com/11 [Java] 차근차근 Java 설치하기 (JDK17, Window 11)자바 개발 도구 설치 방법
keep-programming-study.tistory.com
1. REST API 명세를 문서화하는 방법(Swagger)
1) API 명세 개요, Swagger의 필요성
- 명세: API 개발 시 관리해야 하는 것
-> 해당 API가 어떤 로직을 수행하는지 설명하고,
그 로직을 수행하기 위해 어떤 값을 요청하고 어떤 응답값을 받을 수 있는지를 정리한 자료 - API는 개발 과정에서 계속 변경되므로 작성한 명세 문서도 주기적으로 업데이트가 필요
-> 명세 작업은 번거롭고 시간이 오래 걸리므로, 이를 해결하기 위해 Swagger 오픈소스 프로젝트 등장
2) 스프링부트 프로젝트에서 Swagger를 사용하는 방법
(1) Maven Repository 사이트에서 Swagger 의존성 찾기(https://mvnrepository.com/search?q=springdoc-openapi-starter-webmvc-ui)
- SpringFox Swagger2
: Swagger 문서 생성을 위한 핵심 라이브러리로,
Spring MVC의 컨트롤러와 API를 분석해 Swagger 스펙(JSON)을 자동 생성 - SpringFox Swagger UI
: Swagger UI를 웹 페이지로 제공하는 라이브러리로,
SpringFox Swagger2에서 생성된 Swagger JSON을 기반으로 브라우저에서 시각적으로 API를 확인 및 테스트 - springdoc-openapi: Spring Boot 애플리케이션에서 OpenAPI 3.0 기반의 API 문서를 자동으로 생성해주는 라이브러리
-> 기존의 SpringFox Swagger를 대체하는 최신 도구로, 특히 Spring Boot 3.x와의 호환성이 뛰어남 - STS 3.0.0 이상부터는 springfox-boot-starter라는 통합 의존성이 제공되어, 하나만 추가하면 두 기능을 모두 사용할 수 있음
(2) 프로젝트의 build.gradle 파일에 의존성 추가
... 생략 ...
dependencies {
... 생략 ...
// https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui
// OpenAPI 3.0 + Swagger UI 지원 라이브러리
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9'
}
(3) build.gradle 파일 우클릭 -> Gradle -> Rerfesh Gradle Project 클릭
- build.gradle에 새로운 라이브러리를 추가하거나 버전을 변경했을 때, STS는 이를 자동으로 반영 X
-> Refresh를 실행해야 Gradle이 다시 실행되고, 필요한 JAR 파일을 다운로드한 후 클래스 패스(classpath)에 반영
(4) 기존의 SpringFox Swagger와 다르게,
Swagger 설정 코드 작성 없이 서버를 재시작하고 localhost:8080/swagger-ui/index.html로 접속
(5) 기존 코드에 Swagger 명세를 추가한 후 localhost:8080/swagger-ui/index.html로 다시 접속해보기
- @Tag: Swagger UI에서 API 그룹을 나눌 때 사용
- @Operation: 각 API 엔드포인트의 제목과 설명을 정의
- @ApiResponses: 응답 코드별 설명을 추가 (200, 500 등)
- @Parameter: 요청 파라미터에 대한 설명, 예시, 필수 여부 등을 Swagger 문서에 표시
- @RequestParam: HTTP GET 요청에서 쿼리 파라미터를 받기 위한 Spring 어노테이션
- @Operation: API의 제목과 설명을 Swagger 문서에 표시
package com.example.demo.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// Swagger UI에서 이 컨트롤러를 "Hello API"라는 태그로 그룹화
@Tag(name = "Hello API", description = "간단한 인사말을 반환하는 API")
@RestController
@RequestMapping("/api")
public class GetController {
// Swagger 문서에 이 엔드포인트의 설명을 추가
@Operation(summary = "이름 기반 인사말 반환", description = "요청한 이름을 포함한 인사말을 반환합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 인사말을 반환함"),
@ApiResponse(responseCode = "400", description = "잘못된 요청"),
@ApiResponse(responseCode = "500", description = "서버 오류 발생")
})
@GetMapping("/hello")
public String sayHello(
@Parameter(description = "사용자의 이름", example = "익명") @RequestParam(required = false) String name
) {
return "Hello, " + (name != null ? name : "Spring Boot") + "!";
}
}
2. 로깅 라이브러리(Logback)
1) 로깅(logging) 개요
- 로깅(logging): 애플리케이션이 실행되는 동안 발생하는 이벤트/오류/상태 변화 등을 기록하는 행위
-> 이 기록을 로그(log)라고 하며, 주로 텍스트 파일이나 콘솔에 출력 - 운영 환경에서 시스템을 안정적으로 유지하고 문제를 빠르게 해결하기 위한 필수 도구
*로깅의 주요 목적
- 오류 추적: 예외나 버그 발생 시 원인 파악
- 성능 모니터링: 처리 시간/리소스 사용량 등을 분석
- 사용자 활동 기록: 보안 및 감사 로그로 활용
- 시스템 상태 확인: 정상 동작 여부 실시간으로 확인
2) 로깅 라이브러리의 필요성
- 확장성과 효율성을 위해 로깅 라이브러리를 사용
로그 레벨 관리 | DEBUG, INFO, WARN, ERROR 등으로 로그의 중요도 구분 가능 |
출력 대상 설정 | 콘솔, 파일, 원격 서버 등 다양한 출력 방식 지원 |
로그 포맷 지정 | 시간, 클래스명, 메시지 등 형식을 자유롭게 설정 가능 |
로그 회전 및 보관 | 오래된 로그를 자동으로 압축하거나 삭제하여 디스크 관리 |
비동기 로깅 | 성능 저하 없이 로그 기록 가능 (특히 고트래픽 환경에서 중요) |
구조화된 로깅 | JSON 형식 등으로 로그를 기록해 분석 도구와 쉽게 연동 가능 |
3) 자바 진영에서 많이 사용하는 로깅 라이브러리, Logback의 특징
- 스프링 부트에서는 spring-boot-starter-web 라이브러리 내부에 내장되어 있어, 별도 의존성을 추가하지 않아도 됨
- SLF4J의 구현체로, Log4J를 토대로 만든 프레임워크
(1) 고성능과 메모리 효율성
- Logback은 Log4j보다 월등한 성능을 제공하며, 메모리 사용도 더 효율적
- 내부 구조가 최적화되어 있어 대규모 애플리케이션에서도 안정적으로 작동
(2) 5개 로그 레벨 지원
- TRACE → DEBUG → INFO → WARN → ERROR 순으로 로그의 중요도를 설정
- 로그 레벨을 설정하면 해당 레벨 이상의 로그만 출력되므로, 환경에 따라 유연한 로그 필터링 가능
로그 레벨 | 설명 | 사용 예시 | 중요도 |
TRACE | 가장 상세한 로그로, 디버깅을 위한 내부 흐름 추적에 사용 | 메서드 진입/종료, 루프 내부 상태 확인 | 매우 낮음 |
DEBUG | 개발 중 디버깅을 위한 정보를 (시스템 상태, 변수 값 등) 확인 | 요청 파라미터, DB 쿼리, 캐시 동작 | 낮음 |
INFO | 일반적인 운영 정보로, 시스템의 정상 동작 흐름을 기록 | 서버 시작, 사용자 로그인, 작업 완료 | 중간 |
WARN | 경고 상황으로, 오류는 아니지만 주의가 필요한 상태 | 디스크 공간 부족, API 응답 지연 | 높음 |
ERROR | 오류 발생 상황으로, 시스템 기능에 문제가 생긴 경우 | 예외 발생, DB 연결 실패 등 | 매우 높음 |
(3) 다양한 출력 방식(Appender)
- 콘솔, 파일, 이메일, DB 등 다양한 대상에 로그를 출력할 수 있습니다.
- 대표적인 Appender
- ConsoleAppender: 콘솔 출력
- FileAppender: 파일 저장
- RollingFileAppender: 날짜 또는 크기 기준으로 로그 파일 분할
- SMTPAppender: 이메일 전송
- DBAppender: 데이터베이스 저장
(4) 설정 파일 핫 리로드
- logback.xml 또는 logback-spring.xml 설정 파일을 일정 시간마다 스캔하여, 애플리케이션 재시작 없이 설정 변경 가능
(5) 로그 압축 및 보관 기간 설정
- 오래된 로그를 자동으로 압축하거나 삭제할 수 있어 디스크 공간을 효율적으로 관리
(6) SLF4J와의 통합
- Logback은 SLF4J(Simple Logging Facade for Java)의 구현체로,
SLF4J를 통해 다른 로깅 프레임워크와 쉽게 교체하거나 통합 가능
(7) 구조화된 로그 포맷 지원
- 로그 출력 형식을 자유롭게 설정할 수 있으며, 날짜/클래스명/스레드명 등 다양한 정보를 포함
- 예: [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] %logger %msg%n
4) 스프링부트 프로젝트에 Logback 설정 및 적용
- 공식 사이트 매뉴얼 참고: https://logback.qos.ch/manual/introduction.html
Chapter 1: Introduction
The morale effects are startling. Enthusiasm jumps when there is a running system, even a simple one. Efforts redouble when the first picture from a new graphics software system appears on the screen, even if it is only a rectangle. One always has, at ever
logback.qos.ch
(1) 프로젝트의 src/main/resources 경로에 logback-spring.xml 파일 추가
<?xml version="1.0" encoding="UTF-8"?>
<!-- 콘솔 로깅 출력 -->
<configuration>
<!-- 로그 출력 형식 정의 -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 콘솔에만 로그 출력 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 루트 로거 설정: 로그 레벨과 출력 대상 지정(INFO 이상의 로그들만 출력) -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
(2) 프로젝트에 Logback을 적용
package com.example.demo.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import lombok.extern.slf4j.Slf4j; // Lombok의 로깅 어노테이션
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// Swagger UI에서 이 컨트롤러를 "Hello API"라는 태그로 그룹화
@Tag(name = "Hello API", description = "간단한 인사말을 반환하는 API")
@RestController
@RequestMapping("/api")
@Slf4j // Logback 로거 자동 주입
public class GetController {
// Swagger 문서에 이 엔드포인트의 설명을 추가
@Operation(summary = "이름 기반 인사말 반환", description = "요청한 이름을 포함한 인사말을 반환합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 인사말을 반환함"),
@ApiResponse(responseCode = "400", description = "잘못된 요청"),
@ApiResponse(responseCode = "500", description = "서버 오류 발생")
})
@GetMapping("/hello")
public String sayHello(
@Parameter(description = "사용자의 이름", example = "익명") @RequestParam(name = "name", required = false) String name) {
// 로그 출력 예시
log.info("요청받은 이름: {}", name);
log.debug("sayHello 메서드 실행됨");
String greeting = "Hello, " + (name != null ? name : "Spring Boot") + "!";
log.info("응답 메시지: {}", greeting);
return greeting;
}
}
(3) 서버를 재시작하고, localhost:8080/api/hello?name=학생을 주소창에 입력