[Springboot] swagger(스웨거) 설정 및 사용 방법 예제 코드, DTO가 아닌 맵을 사용중이라면?
이전 모 통신사 프로젝트할때 스웨거라는 api 툴을 처음 접했다. postman으로 api를 테스트 했는데, 스웨거라는 사이트에 접근해서 단위 테스트를 해서 거증을 뜨라는게 아닌가? 그래서 별도의 시스템을 구축한건가 라고 생각하고 넘어갔는데, 오늘 스웨거 도입을 위해 환경 구성하면서 알게되었다. 라이브러리를 가져다 사용한다는 사실을!!! 고맙다 ChatGpt!!
내가 모르는 부분에 대해 웹검색해서 찾아다니는데 걸리는 시간들이 이제 모두 keep되고 있다.
웹검색 시대는 끝난것으로 생각한다.
나의 말:
api테스트를 해야하는데 스웨거를 해보고 싶어
ChatGPT의 말:
스웨거(Swagger)는 API 문서를 자동으로 생성하고, 바로 브라우저에서 API를 테스트할 수 있어서 개발할 때 많이 씁니다 👍
지금 상황에 맞춰 크게 2가지 경우로 나눠서 알려드릴게요.
1️⃣ Spring Boot + Swagger (springdoc-openapi)
Spring Boot 환경이라면 보통 springdoc-openapi 라이브러리를 씁니다.
Gradle 예시:
dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
}
Maven 예시:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
추가 후 서버를 실행하면 자동으로 아래 URL이 생깁니다:
- Swagger UI :
http://localhost:8080/swagger-ui/index.html
- OpenAPI Docs(JSON) :
http://localhost:8080/v3/api-docs
→ 여기서 바로 API 테스트 가능해요.
2️⃣ 스프링이 아니라면 (예: Node.js, Python 등)
- Node.js →
swagger-ui-express
,swagger-jsdoc
- Python(FastAPI, Flask) → FastAPI는 기본 Swagger 지원, Flask는
flasgger
같은 라이브러리 - 단순히 API 테스트만 하고 싶다면 → Swagger Editor (https://editor.swagger.io/) 를 켜서 OpenAPI 스펙을 작성하면, 바로 실행해볼 수 있습니다.
3️⃣ 빠른 확인 (서버 코드 필요 없음)
만약 직접 서버에 붙이지 않고 Swagger만 체험하고 싶다면:
- Swagger Editor 접속
- 왼쪽 YAML에 API 정의 작성
- 오른쪽에서 바로 실행 버튼으로 테스트
예시 YAML:
openapi: 3.0.0
info:
title: Sample API
version: 1.0.0
paths:
/hello:
get:
summary: "헬로 API"
responses:
"200":
description: 성공
👉 혹시 지금 API가 Spring Boot 기반이에요, 아니면 다른 서버(Node.js, Python 등) 에서 돌고 있는 건가요?
그거에 맞춰 설치 방법을 바로 예제 코드로 정리해드릴게요.
나의 말:
Spring Boot 기반이야
ChatGPT의 말:
좋습니다 🙌 Spring Boot 기반이라면 springdoc-openapi 쓰는 게 제일 간단해요.
✅ Spring Boot + Swagger(springdoc-openapi) 적용 방법
1. 의존성 추가
Gradle 기준:
dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
}
Maven 기준:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
2. 서버 실행 후 접근
서버 띄우면 자동으로 Swagger UI와 API 문서가 열려요.
- Swagger UI :
http://localhost:8080/swagger-ui/index.html
- OpenAPI JSON 문서:
http://localhost:8080/v3/api-docs
3. 예시 컨트롤러
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello Swagger!";
}
}
이제 서버 띄우고 http://localhost:8080/swagger-ui/index.html
들어가면
👉 /api/hello
API가 Swagger 문서에 자동으로 표시되고, 거기서 바로 테스트 버튼 눌러 호출할 수 있습니다.
4. (선택) Swagger 문서 커스터마이징
application.yml
에서 경로 바꿀 수도 있어요:
springdoc:
swagger-ui:
path: /swagger
api-docs:
path: /api-docs
→ 그러면 Swagger UI는 http://localhost:8080/swagger
, 문서는 /api-docs
로 접속됩니다.
👉 혹시 원하시는 게 단순히 내 API 문서 자동 생성 + 테스트 인지, 아니면 커스터마이징된 문서 (API 설명/예제 추가) 까지도 필요하세요?
나의 말:
implementation ‘org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0’ <–버전을 낮춰봐 Caused by: java.lang.IllegalArgumentException: Unresolvable class definition for class [org.springdoc.core.conditions.SpecPropertiesCondition] at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:331) at org.springframework.context.annotation.ConditionEvaluator.getCondition(ConditionEvaluator.java:124) at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:96) at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:225) at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:599) … 49 common frames omitted Caused by: java.lang.UnsupportedClassVersionError: org/springdoc/core/conditions/SpecPropertiesCondition has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 59.0 (클래스 [org.springdoc.core.conditions.SpecPropertiesCondition]을(를) 로드할 수 없습니다) at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2341) at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:810) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1293) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1141) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:468) at org.springframework.util.ClassUtils.forName(ClassUtils.java:284) at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:324) … 53 common frames omitted
ChatGPT의 말:
에러 메시지 핵심이 여기예요 👇
java.lang.UnsupportedClassVersionError:
... SpecPropertiesCondition has been compiled by a more recent version of the Java Runtime (class file version 61.0),
this version of the Java Runtime only recognizes class file versions up to 59.0
- 클래스 파일 버전 61 = JDK 17
- 클래스 파일 버전 59 = JDK 15
즉, 현재 서버는 Java 15 이하에서 돌고 있는데,springdoc-openapi-starter-webmvc-ui:2.5.0
은 JDK 17 이상으로 빌드된 라이브러리라서 호환이 안 되는 거예요.
해결 방법 2가지
🔹 방법 1: JDK 업그레이드
가장 권장되는 방법이에요.
- 서버 JDK를 17 이상으로 올리면 → 최신 springdoc (2.x) 버전을 그대로 사용 가능.
🔹 방법 2: springdoc 버전 낮추기
만약 JDK 업그레이드가 불가능하다면, 1.6.x
라인 사용하세요.
이 버전은 Java 8 이상에서 동작합니다.
예시 (Gradle):
dependencies {
implementation 'org.springdoc:springdoc-openapi-ui:1.6.15'
}
예시 (Maven):
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.15</version>
</dependency>
👉 1.x 버전에서는 모듈명이 다릅니다:
springdoc-openapi-ui
(WebMVC)springdoc-openapi-webflux-ui
(WebFlux)
✅ 정리
- JDK 17 이상 →
springdoc-openapi-starter-webmvc-ui:2.x
- JDK 8~11, 15 →
springdoc-openapi-ui:1.6.15
👉 혹시 지금 서버 JDK 버전 몇인지 알아요? (java -version
찍어보면 됨)
나의 말:
인증관련 오류가 발생해
ChatGPT의 말:
스크린샷 보니까 Swagger UI 접속은 됐는데, API 호출할 때
"code":"E0003","message":"로그인이 필요합니다."
라는 에러가 떨어지고 있네요.
즉, Swagger 자체 문제는 아니고, 프로젝트에 걸려있는 로그인/인증(Spring Security) 때문에 Swagger 요청이 막히는 상황이에요.
해결 방법
🔹 1. Swagger 페이지 접근은 허용하기
WebSecurityConfigurerAdapter
(Spring Security) 설정에서 Swagger 관련 URL을 permitAll 처리해주면 됩니다.
예시 (Spring Security 5.x, SecurityConfig.java):
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
// Swagger 관련 리소스 허용
.antMatchers(
"/v3/api-docs/**",
"/swagger-ui.html",
"/swagger-ui/**"
).permitAll()
// 그 외 요청은 인증 필요
.anyRequest().authenticated()
.and()
.formLogin(); // 로그인 방식은 프로젝트 상황에 맞게
}
}
Spring Security 6.x (Spring Boot 3.x)라면 DSL 방식이 바뀌어서 이렇게:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/v3/api-docs/**",
"/swagger-ui.html",
"/swagger-ui/**"
).permitAll()
.anyRequest().authenticated()
);
return http.build();
}
🔹 2. Swagger UI에서 인증 토큰 붙여주기
만약 API 테스트 자체가 인증이 필요하다면 → Swagger UI에서 로그인 후 토큰을 넣어야 합니다.
springdoc-openapi에서는 SecurityScheme을 설정해주면 됩니다.
예시:
@OpenAPIDefinition(
security = @SecurityRequirement(name = "bearerAuth")
)
@SecurityScheme(
name = "bearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
)
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
→ 그러면 Swagger UI에 Authorize 버튼이 생기고, JWT 토큰 입력 후 모든 요청에 자동으로 붙습니다.
✅ 정리
- 단순히 Swagger 화면 접속이 막힌 경우 → SecurityConfig에서 Swagger 리소스 permitAll.
- API 자체가 인증 필요한 경우 → Swagger SecurityScheme 등록해서 토큰 붙이는 방식으로 테스트.
👉 지금 원하는 게 Swagger 페이지 접속만 풀고 싶은 건가요, 아니면 API 테스트할 때 로그인/토큰 입력까지 가능하게 하고 싶은 건가요?
나의 말:
/v3/api-docs/ 없나본데?
ChatGPT의 말:
좋은 포인트예요 👍
/v3/api-docs
경로는 springdoc-openapi 2.x (Spring Boot 3.x, JDK 17 이상) 기준이에요.
앞에서 버전 문제 때문에 1.x (예: 1.6.15) 로 내렸잖아요?
👉 1.x
버전에서는 경로가 다릅니다.
springdoc-openapi 1.x (Java 8~11, Boot 2.x) 기본 경로
- Swagger UI :
http://localhost:8080/swagger-ui.html
- OpenAPI JSON 문서 :
http://localhost:8080/v2/api-docs
springdoc-openapi 2.x (Java 17 이상, Boot 3.x) 기본 경로
- Swagger UI :
http://localhost:8080/swagger-ui/index.html
- OpenAPI JSON 문서 :
http://localhost:8080/v3/api-docs
즉, 지금은 /v2/api-docs
가 맞을 가능성이 높습니다.
👉 한번 브라우저에서
http://localhost:8080/v2/api-docs
접속해보실래요?
만약 JSON 스펙이 뜬다면 Swagger UI도 정상 연결될 거예요.
원하시면 제가 SecurityConfig
예시도 1.6.x 버전 스타일로 다시 맞춰드릴까요?
나의 말:
modelAndView 입력안해도 되거든? controller에서 뭐 어노테이션 같은거 넣어야해?
ChatGPT의 말:
아하 👍 지금 Swagger UI에서 modelAndView
라는 복잡한 객체를 QueryParam으로 요구하고 있네요.
그런데 실제로는 API 호출할 때 이 파라미터 안 받아도 된다 → Swagger 문서 생성 과정에서 잘못 스캔된 겁니다.
원인
springdoc은 기본적으로 컨트롤러 메서드의 파라미터 타입을 보고 자동으로 Swagger 모델을 만듭니다.
아마 컨트롤러가 대충 이런 형태일 거예요:
@GetMapping("/getNoticeList")
public List<Notice> getNoticeList(ModelAndView modelAndView ) {
...
}
- 이렇게 하면 springdoc이
modelAndView
를 Query Parameter 객체로 인식해서 Swagger에 표시해버립니다. - 하지만 실제로는 이 인자가 내부 처리용이거나 무시 가능한 경우죠.
해결 방법
1. Swagger 문서에서 제외시키기
Swagger 문서에 노출시키고 싶지 않은 파라미터라면 @Parameter(hidden = true)
붙이면 됩니다:
@GetMapping("/getNoticeList")
public List<Notice> getNoticeList(@Parameter(hidden = true) ModelAndView modelAndView ) {
...
}
2. 아예 스캔 대상에서 빼기
공용으로 쓰이는 ModelAndView 같은 타입을 전역적으로 Swagger 스캔에서 제외하려면 @Hidden
어노테이션을 클래스에 붙일 수도 있어요:
import io.swagger.v3.oas.annotations.Hidden;
@Hidden
public class ModelAndView {
...
}
3. (권장) API 파라미터만 명확히 선언
정말 API가 외부에서 받을 값만 Swagger에 표시하려면 메서드 시그니처를 바꾸는 게 제일 깔끔합니다:
@GetMapping("/getNoticeList")
public List<Notice> getNoticeList(
@RequestParam(required = false) String keyword,
@RequestParam(required = false) Integer page
) {
...
}
✅ 정리
- 특정 파라미터 Swagger에서 숨기고 싶다 →
@Parameter(hidden = true)
- 클래스 단위로 숨기고 싶다 →
@Hidden
- 문서에 정확한 API 스펙만 보이게 하려면 컨트롤러 파라미터를
@RequestParam
,@RequestBody
등으로 명확히 지정하기
👉 혹시 지금 modelAndView
는 Spring MVC에서 자동 주입되는 내부 객체인가요, 아니면 프로젝트 커스텀 객체인가요?
나의 말:
니가 하라는데로 했더니, 데이터 맵핑도 안되는데?
ChatGPT의 말:
좋은 지적이에요 👍
제가 @Parameter(hidden = true)
를 추천했을 때는 Swagger 문서에서만 숨기고 실제 실행은 그대로 유지할 수 있을 거라고 본 건데,
아마 지금 구조상 TmsModelAndView
가 컨트롤러 인자에서 빠지면서 스프링의 파라미터 바인딩도 같이 깨진 것 같습니다.
⚡ 정리해보면
Swagger 문서에서는 안 보이게 하고 싶음
실제 코드 실행에서는 여전히 스프링이 바인딩해줘야 함
→ 이럴 땐 Swagger만 무시하게 처리해야 해요.
✅ 해결 방법 2가지
1. @Operation
안에 parameters = {}
설정
메서드 단위로 Swagger 문서를 오버라이딩해서 불필요한 파라미터를 숨깁니다:
@Operation(
summary = "공지사항 목록 조회",
description = "공지사항 리스트 반환",
parameters = {}
)
@GetMapping("/getNoticeList")
public List<Notice> getNoticeList(ModelAndView modelAndView ) {
return service.getNoticeList(modelAndView );
}
👉 이렇게 하면 Swagger 문서에는 modelAndView
가 안 보이지만,
스프링은 여전히 정상적으로 파라미터 매핑을 수행합니다.
2. @Parameter(hidden = true)
+ @RequestParam
/@RequestBody
로 진짜 API 파라미터만 표시
만약 외부 호출자가 알아야 할 파라미터가 별도로 있다면, tmsModelAndView
는 숨기고 필요한 것만 Swagger에 노출:
@GetMapping("/getNoticeList")
public List<Notice> getNoticeList(
@Parameter(hidden = true) ModelAndView modelAndView ,
@RequestParam(required = false) String keyword
) {
return service.getNoticeList(modelAndView , keyword);
}
✅ 추천은 1번 (@Operation(parameters = {})
) 방식이에요.
→ Swagger 문서와 실제 코드 실행을 완전히 분리할 수 있고, 매핑도 그대로 유지됩니다.
👉 지금 tmsModelAndView
는 공통 처리용 객체 (로그인 정보, 세션값 등) 같은 거 맞나요?
그렇다면 Swagger 문서에는 안 보이게 하고, 서비스 내부에서는 그대로 쓰게 하는 게 제일 자연스러워요.
나의 말:
@PostMapping(“getToken”) public ModelMap getToken(@RequestBody Map<String, Object> json, ModelAndView modelAndView ) { 이렇게 되어 있네;.. 스웨거 사용가능한 상태야?

ChatGPT의 말:
네 👍 지금 코드 보면 이렇게 되어 있죠:
@PostMapping("getToken")
public ModelMap getToken(@RequestBody Map<String, Object> json,
ModelAndView mModelAndView ) { ...
}
여기서 상황을 정리해보면:
1. Swagger 동작 여부
@RequestBody Map<String,Object> json
→ Swagger에서는 Body 파라미터로 노출됨 ✅ModelAndView
→ Swagger가 자동으로 인식해서 Query 파라미터 객체처럼 표시될 가능성 있음 ❌ (앞에서처럼 필요 없는 입력폼이 생김)
즉, 지금 상태 그대로도 Swagger는 사용 가능합니다.
하지만 mModelAndView 때문에 Swagger 화면에 불필요한 입력 칸이 보일 거예요.
2. 해결 방법 (Swagger에는 숨기고, 실제 실행은 유지)
ModelAndView 는 실제 코드에서는 필요하지만, Swagger 문서에는 안 보이게 하면 됩니다.
방법 A: @Parameter(hidden = true)
@PostMapping("getToken")
public ModelMap getToken(@RequestBody Map<String, Object> json,
@Parameter(hidden = true) ModelAndView modelAndView) {
...
}
- Swagger 문서에는 안 보이고,
- 실제 실행 시에는 그대로 Spring이 주입해줍니다.
방법 B: 메서드 단위로 Swagger 문서 재정의
@Operation(
summary = "토큰 발급",
description = "로그인 후 사용할 토큰을 발급받는다",
parameters = {}
)
@PostMapping("getToken")
public ModelMap getToken(@RequestBody Map<String, Object> json,
ModelAndView modelAndView ) {
...
}
parameters = {}
로 지정하면 Swagger에 불필요한 파라미터가 표시되지 않습니다.
혹시 원하시는 게
- Swagger에서 그냥
json
Body만 보이게 하고 싶다 - 아니면
tmsModelAndView
도 일부 필드는 노출하고 싶다
둘 중 어떤 쪽인가요?
나의 말:
ChatGPT의 말:
좋은 질문이에요 👍
현재 메서드는 이렇게 되어 있죠:
@PostMapping("getToken")
public ModelMap getToken(@RequestBody Map<String, Object> json,
TmsModelAndView tmsModelAndView) {
Box box = new Box(json);
return mainInfoService.getTokenAOS(box, tmsModelAndView);
}
🔹 Swagger에서 Map<String,Object> 입력하는 방법
Swagger UI에서 Map<String, Object>
는 그냥 JSON 객체로 입력하면 됩니다.
예를 들어, Box
안에서 사용하는 키가
userId
password
라면 Swagger UI Request body
에 이렇게 넣으면 됩니다:
{
"userId": "testUser",
"password": "1234"
}
🔹 Swagger에서 입력 시 주의사항
- Swagger에서 Map은 JSON 오브젝트로 매핑됩니다.
{ "key1": "value1", "key2": 123, "key3": true }
Box box = new Box(json)
으로 래핑되므로,
Box 안에서는box.getString("userId")
,box.getString("password")
이런 식으로 꺼낼 수 있습니다.- Swagger에서
Map<String,Object>
를 좀 더 보기 좋게 하려면, DTO 클래스를 만들어주는 게 제일 깔끔해요.
예:
public class TokenRequest {
private String userId;
private String password;
// getter/setter
}
그리고 컨트롤러를:
@PostMapping("getToken")
public ModelMap getToken(@RequestBody TokenRequest req,
TmsModelAndView tmsModelAndView) {
Box box = new Box(Map.of(
"userId", req.getUserId(),
"password", req.getPassword()
));
return mainInfoService.getTokenAOS(box, tmsModelAndView);
}
이렇게 하면 Swagger에서도 입력폼이 자동으로 예쁘게 생성됩니다.
🔹 정리
- 지금 상태에서는 Swagger Request Body에 그냥 JSON 객체 넣으면 됩니다.
- 예시:
{ "userId": "abc", "password": "xyz" }
- 더 깔끔하게 하려면
Map
대신 DTO 클래스를 만들어 쓰면 Swagger에서 자동으로 스키마 보여주기 때문에 훨씬 편합니다.
👉 혹시 Swagger에서 Box
를 직접 인식하게 해서 입력폼을 자동으로 만들고 싶은 건가요? 아니면 그냥 Map을 JSON으로 입력하는 방법만 필요하신 건가요?
나의 말:
{
"empty": true,
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
이렇게 나오거든… 내가 전혀 사용하는 파라미터가 아닌데..
ChatGPT의 말:
보니까 Swagger가 Map<String,Object>
를 만나니까 스키마를 못 만들고
자동으로 additionalProp1
, additionalProp2
같은 generic map placeholder만 만들어놨어요.
그래서 실제 API에서 쓰는 파라미터(예: userId
, password
)가 전혀 보이지 않는 거예요.
🔹 왜 이렇게 되냐?
- Swagger (springdoc)는 DTO 클래스의 필드를 스캔해서 API 문서를 만드는데,
Map<String,Object>
는 키와 값이 동적으로 들어오니 무슨 필드가 있는지 Swagger가 알 수 없음 → 그래서 저런 placeholder만 나옴.
🔹 해결 방법
1. DTO 클래스 정의 (추천 👍)
Swagger에서 예쁘게 스키마 나오게 하려면, DTO를 정의하는 게 가장 확실합니다.
public class TokenRequest {
private String userId;
private String password;
// getter/setter
}
컨트롤러:
@PostMapping("getToken")
public ModelMap getToken(@RequestBody TokenRequest req,
ModelAndView modelAndView ) {
Box box = new Box(Map.of(
"userId", req.getUserId(),
"password", req.getPassword()
));
return mainInfoService.getTokenAOS(box, modelAndView );
}
➡ Swagger 화면에 userId
, password
입력폼이 자동으로 뜹니다.
2. Map 그대로 쓰되, Swagger 문서만 수동 정의
DTO 만들기 싫다면, @Schema
나 @RequestBody
의 content
를 직접 지정해서 Swagger에 설명을 넣을 수 있습니다.
@Operation(summary = "토큰 발급",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
required = true,
content = @Content(
schema = @Schema(
example = "{ \"userId\": \"abc\", \"password\": \"1234\" }"
)
)
)
)
@PostMapping("getToken")
public ModelMap getToken(@RequestBody Map<String, Object> json,
TmsModelAndView tmsModelAndView) {
Box box = new Box(json);
return mainInfoService.getTokenAOS(box, tmsModelAndView);
}
➡ Swagger에서 여전히 Map
을 받지만, 화면에 예시 JSON이 보이게 됩니다.
3. Box 타입을 Swagger에 노출시키기
Box 클래스가 있다면, Swagger가 인식할 수 있도록 DTO처럼 정의할 수도 있어요.
근데 Box
가 내부 유틸성 래퍼라면 권장하진 않습니다.
✅ 결론
- 지금처럼
Map<String,Object>
만 쓰면 Swagger는additionalProp1
같은 쓰레기 필드만 보여줌 - 실제 파라미터를 Swagger에서 보려면 DTO 클래스를 만들거나, Swagger 어노테이션으로 문서를 수동 정의해야 함
👉 혹시 Box
가 계속 공용으로 쓰이는 구조라서 DTO 만들기 귀찮은 상황인가요?
그렇다면 제가 Map 그대로 쓰면서 Swagger에 예쁘게 문서화하는 방식을 딱 맞춰드릴게요.
Is this conversation helpful so far?
나의 말:
응 DTO를 만들 수 없는 상황이야.. 이미 프로젝트가 완료되었어.
ChatGPT의 말:
오케이 ✅ 이해했어요. 이미 프로젝트가 완료된 상태라 DTO로 갈아타긴 어렵고, Map<String, Object>
를 유지하면서 Swagger 화면에서만 보기 좋게 하고 싶은 거죠.
그럴 땐 Swagger 어노테이션으로 requestBody를 커스터마이징 하면 됩니다.
🔹 방법 1: @Operation
+ @RequestBody
(springdoc-openapi)
@Operation(
summary = "토큰 발급",
description = "사용자 ID와 패스워드를 받아 토큰을 발급합니다.",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
required = true,
content = @Content(
mediaType = "application/json",
schema = @Schema(
example = "{ \"userId\": \"testUser\", \"password\": \"1234\" }"
)
)
)
)
@PostMapping("getToken")
public ModelMap getToken(@RequestBody Map<String, Object> json,
ModelAndView modelAndView) {
Box box = new Box(json);
return mainInfoService.getTokenAOS(box, modelAndView);
}
➡ Swagger UI에서 이제 additionalProp1
같은 거 안 나오고,
Request body 예시에 userId
랑 password
가 뜹니다.
🔹 방법 2: @Schema
정의만 사용
@PostMapping("getToken")
@io.swagger.v3.oas.annotations.parameters.RequestBody(
required = true,
content = @Content(
schema = @Schema(
example = "{ \"userId\": \"abc\", \"password\": \"1234\" }"
)
)
)
public ModelMap getToken(@RequestBody Map<String, Object> json,
ModelAndView modelAndView) {
Box box = new Box(json);
return mainInfoService.getTokenAOS(box, modelAndView);
}
➡ DTO 없이 Map 그대로 두고, 예시만 보여줌.
🔹 방법 3: 커스텀 @Schema
로 여러 필드 문서화
Swagger 문서에 필드 설명까지 넣고 싶다면:
@Operation(
summary = "토큰 발급",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
required = true,
content = @Content(
mediaType = "application/json",
schema = @Schema(
type = "object",
properties = {
@SchemaProperty(
name = "userId",
schema = @Schema(type = "string", example = "testUser")
),
@SchemaProperty(
name = "password",
schema = @Schema(type = "string", example = "1234")
)
}
)
)
)
)
➡ 이렇게 하면 Swagger UI에서 필드별 설명까지 노출됩니다.
📌 즉, Map을 유지하면서 Swagger UI에서 DTO처럼 보이게 할 수 있음 →
추천은 방법 1 (예시 JSON만) or 방법 3 (필드 설명까지) 입니다.