avatar
BrightDawn

스프링 부트 3.1.3에서 Swagger UI사용하기

스프링 부터 3.xx부터는 Swagger UI의 사용법이 다르다는 것, 알고 계셨나요? 저는 몰라서 고생 좀 했습니다.
6 months ago
·
6 min read

Swagger UI란 무엇인가?

Swagger UI는 Swagger의 라이브러리 중 API Documentation, API 명세와 관련된 기능을 제공하는 라이브러리이다.

쉽게 말하자면 API 자동 시각화이다. 아마 Swagger에 대해서 들어보지 못한 사람들도 얼추 이 비슷한 화면을 본 적은 있을 것이다.

until-770

이게 Swagger-ui를 통해서 만들어진 화면이다. 딱 Swagger-ui 세팅만 해주고 내가 필요한 컨트롤러를 넣어주기만 하면 알아서 만들어준다.

그런데 왜 하필 Spring boot 3.1.3인가?

Swagger를 사용하기 위해 찾아보면 대다수의 글들은 이렇게 말할 것이다.

gradle을 사용하고 있다면 아래 코드를 통해서 의존성 추가를 하세요!

implementation 'io.springfox:springfox-boot-starter:3.0.0'

맞는 이야기다. 맞는 이야기인데, Spring boot 3.1.3을 쓰고 있는 사람과 나에게는 맞는 이야기'였'다. 과거형이란 소리다. springfox는 Spring boot 3.xx를 지원하지 않는다. 이대로 코드를 실행시키면, 아니 실행 전에 일단 gradle부터 리로드 하는 순간 오류를 발산해준다.

일단 빨간색으로 build failed부터 시작해서 이대로 코드 실행하는 순간 아래와 같은 오류를 뱉어준다. 갑자기 HttpServletRequest를 찾을 수 없다느니 뭐라느니...

2024-07-08T15:50:10.045+09:00 ERROR 9440 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

java.lang.TypeNotPresentException: Type javax.servlet.http.HttpServletRequest not present
	at 

... 중략

java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[na:na]
	at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
	at java.base/java.lang.Class.forName(Class.java:467) ~[na:na]
	at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) ~[na:na]
	... 37 common frames omitted


종료 코드 0(으)로 완료된 프로세스

그럼 Spring 3.1.3은 Swagger-ui를 포기해야하는가?

하늘이 무너져도 솟아날 구멍은 있다. 이런 API 명세 날로 먹기 기능을 사람들이 포기했을 리가 없다.

열심히 찾아본 결과, 우리는 springfox의 버림을 받은 대신, springdoc-openapi를 사용해주면 된다는 사실을 알 수 있었다.


Swagger-ui 적용하기

환경내역

먼저 내가 사용하고 있는 환경은 다음과 같다.

Java 버전 17, Spring boot 3.1.3, 개발 툴 IntelliJ, Spring Security 적용 중, gradle 기반.

의존성 추가

우리가 써온 모든 것들이 그래왔듯이 의존성 추가를 해주어야 한다.

아래 코드를 build.gradle파일의 dependencies 블록에 넣어주자. 그리고 gradle을 refresh 해주는 것을 잊지 말자.

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' 

SwaggerConfig 파일 세팅

SwaggerConfig 파일을 만들 건데, 나의 경우에는 내가 사용하고 있는 패키지의 기본 패키지에 config폴더를 만들어서 그 안에 넣어주었다. SwaggerConfig.java클래스 파일을 만들어주면 된다.

package 패키지명;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SwaggerConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
            .info(new Info()
                  .title("제목")
                  .version("버전")
                  .description("디스크립션 문서"));
    }
}

위 내용을 참고하여 필요한 것이 있다면 더 추가해주면 된다.

여기까지 하고서 실행했는데 안 되는데요?

당신도 나와 같은 Spring Security를 사용하고 있는 모양이다. 보안상에는 좋다지만 개발하는 입장에서는 불편하기 그지없다. 하지만 보안이 우선인데 어쩌겠는가

이미 SecuiryConfig 파일이 존재할텐데, 그 안에다가 아래와 같이 연결해서 넣어주자.

.requestMatchers(new AntPathRequestMatcher("/swagger-ui/**")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/v3/api-docs/**")).permitAll()

어디에 넣어야 할지 감이 안 잡히는 사람들을 위해 import를 제외한 전체 내용 역시 공유하겠다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

	@Bean
	SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.
			authorizeHttpRequests(
					(authorizeHttpRequests) -> authorizeHttpRequests
							.requestMatchers(new AntPathRequestMatcher("/swagger-ui/**")).permitAll()
							.requestMatchers(new AntPathRequestMatcher("/v3/api-docs/**")).permitAll()
					.requestMatchers(new AntPathRequestMatcher("/**")).permitAll())
		.headers(
				(headers) -> headers
				.addHeaderWriter(new XFrameOptionsHeaderWriter(
						XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))).csrf(csrf -> csrf.disable()
			);	
		return http.build();
	}
}

나는 csrf 관련 문제도 생겨서 저렇게 추가 처리 해주었다.

확인하기

위와 같은 단계를 거친 후에, 아래와 같이 링크에 접속해보자.

http://localhost:8080/swagger-ui/index.html#/컨트롤러명

until-772

그럼 위와 같은 사이트에 접속할 수 있다. 아주 익숙한 사이트다.