: RESTful API를 설계, 문서화, 테스트 및 개발할 수 있도록 도와주는 오픈소스 프레임워크이다.
현재는 OpenAPI Specification (OAS)의 일부로 발전했으며, API 문서를 자동으로 생성하고 API의 동작을 쉽게 테스트할 수 있도록 도와준다.
: Spring Boot에서 Swagger 2 및 3 (OpenAPI 3.0)을 지원하는 라이브러리
dependencies {
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
}
springfox 단점
2020년 이후로 업데이트가 없는 상태이다.
공식적으로 OpenAPI 3.0을 완전히 지원하지 않는다.
Spring Boot 3 및 OpenAPI 3.0을 지원하는 Swagger 라이브러리이다.
Swagger UI, JSON/YAML 문서 생성 등을 보다 간단하게 설정할 수 있다.
API 문서 자동 생성
코드에서 API의 엔드포인트, 요청/응답 형식 등을 읽어와 자동으로 문서화합니다.
API 테스트 인터페이스 제공
Swagger UI를 통해 API를 브라우저에서 직접 호출하고 테스트할 수 있다.
API 명세 관리 (OpenAPI Specification)
API의 구조를 JSON 또는 YAML 형식으로 정의할 수 있다.
다양한 언어 및 프레임워크 지원
Spring Boot, Node.js, Django, .NET 등 다양한 기술 스택에서 사용한다.
build.gradle 의존성 추가
dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'
}
controller에 해당 annotation 추가
@RestController
@RequiredArgsConstructor
@RequestMapping("/plan")
@Tag(name = "Plan API", description = "여행 계획 관련 API")
public class PlanController {
private final PlanService planService;
@Operation(summary = "여행 계획 생성", description = "새로운 여행 계획을 생성합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "계획 생성 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 요청")
})
@PostMapping
public ResponseEntity<CommonResDto> planCreate(PlanCreateReqDto planCreateReqDto) {
PlanResDto dto = planService.planCreate(planCreateReqDto);
return new ResponseEntity<>(new CommonResDto(HttpStatus.CREATED, "계획 생성이 성공적으로 완료되었습니다.", dto), HttpStatus.CREATED);
}
}
Swagger UI 접속
http://localhost:8080/swagger-ui/index.html
먼저 간단하게 프로젝트에 대해서 설명하자면
spring security + jwt 를 사용해서 Oauth 로그인을 구현한 상태이다.

Whitelabel 도 아니고 그냥 빈 화면이 나온다.

개발자 모드로 확인하면 401(권한없음) 에러..
(https를 사용해서 진행되는 문제인가 싶어서 포트 변경해서 여러 번 진행하였기 때문에 위 사진과 아래 사진 URL이 동일하지 않습니다. 그러나, 포트와 상관없이 동일하게 위 사진과 같은 흰 화면, 아래 사진 같은 에러가 출력되었습니다!)
구글링 시작
404 에러일 경우 대부분 URL을 잘못 들어갔을 가능성이 있다.
예를 들면
spring fox의 경우는 http://localhost:8080/swagger-ui.html 로 접근해야 하고
spring dox 의 경우는 http://localhost:8080/swagger-ui/index.html로 접근해야 한다.
에러 자체가 다르니깐
당연히 해결되지 않았다...
401 에러가 발생했기 때문에, Spring Security 설정에서 문제가 발생한 것이라고 판단했다.
SecurityConfig 클래스의 SecurityFilterChain 메서드에서 해당 URL을 permitAll()로 설정하여 인증 없이 접근할 수 있도록 수정했다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
log.info("SecurityConfig initialized");
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/login/**",
"/oauth2/**",
"/swagger-ui/**", // swagger 허용
"/v3/api-docs/**" // swagger 허용
).permitAll()
.anyRequest()
.authenticated()
)
.oauth2Login(oauth2 -> oauth2
.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler(oAuth2AuthenticationFailureHandler)
.userInfoEndpoint(userinfo -> userinfo
.userService(customOAuth2UserService))
)
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
근데도 안 보인다...
결론적으로, JWT 필터 내에서 한 번 더 허용된 URL을 확인하는 과정이 있었기 때문에 허용 URL 리스트에 해당 swagger 관련 URL을 추가하는 것이 필요하다.
(프로젝트마다 구성 방식이 조금씩 다를 수 있다.)
securityFilterChain에서 addFilterBefore를 사용했기 때문에, JwtAuthenticationFilter가 UsernamePasswordAuthenticationFilter보다 먼저 실행된다.
그러하여 jwtfilter에서 해당 url들이 허용되지 않아 401 에러가 난 것이다.
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtTokenProvider jwtTokenProvider;
private final String[] whiteList = {"/swagger-ui/**", "/v3/**"};
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String requestURI = request.getRequestURI();
// 화이트리스트에 있는 URL이면 JWT 필터를 건너뜀
if (isWhiteList(requestURI)) {
filterChain.doFilter(request, response);
return;
}
// JWT 검증 로직 (여기서 accessToken 검사 등 진행)
filterChain.doFilter(request, response);
}
private boolean isWhiteList(String uri) {
return Arrays.stream(whiteList)
.anyMatch(pattern -> uri.matches(pattern.replace("**", ".*")));
}
}
위와 같이 white list를 작성하여 진행하였다.
이제 흰 화면은 아닌데 또 에러 발생..
개발 진행하면서 예외 처리를 작성하였는데 에러가 발생하였다.

개발자 모드

끝날 때까지 끝난 게 아니다.
이번에는 500 에러 발생하였다.
swagger 공식 문서
https://springdoc.org/#error-handling-for-rest-using-controlleradvice
알고보니 swagger 버전이 올라가면서 @ControllerAdvice 사용할 경우 충돌 문제가 발생하는 할 수 있다고 한다.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<CommonErrorDto> IllegalArgumentExceptionHandler (IllegalArgumentException e) {
e.printStackTrace();
return new ResponseEntity<>(new CommonErrorDto(HttpStatus.BAD_REQUEST, e.getMessage()),HttpStatus.BAD_REQUEST);
}
}
코드는 위와 같다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.0'
id 'io.spring.dependency-management' version '1.1.6'
}
dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
}
위와 같은 버전을 아래와 같이 변경하였다. (2025)
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
}
dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
}

잘 실행된다.