개발자에게 문서 작성이란 참 귀찮은 일이다.
하지만, 뭔가 프로토콜을 구현하다보면 문서 작성은 필수적인 일이다.
Swagger는 이런 귀찮은 프로토콜 문서 작성을 자동화 시켜준다.
Swagger 자체부터 파고들면, 어려웠겠지만 Spring MVC전용으로 누군가 커스터마이징해서 올려둔 게 있어서
이걸 적용해 보았다.
[Swagger-SpringMVC 설정 (https://github.com/martypitt/swagger-springmvc)]
1. Maven에 의존성을 추가해준다.
- 현재 Swagger-SpringMVC의 경우 가장 최신버전이 0.9버전인데, Maven Central Repositories에서는 0.88버전인가까지밖에 올라와 있지 않다.
- 0.9버전을 사용하기 위해, Repository를 따로 등록해준다.
<repository>
<id>jcenter-release</id>
<name>jcenter</name>
<url>http://oss.jfrog.org/artifactory/oss-release-local</url>
</repository>
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>0.9.0</version>
</dependency>
2. Jackson을 사용하고 있지 않다면, Jackson도 의존성에 추가해준다. (Swagger-SpringMVC는 내부적으로 JacksonMessageConverter를 사용하기 때문) - 현재 가장 최신버전은 2.4.3이다.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
3. 2번에 설명한 것과 같이 JacksonMessageConverter를 Spring Config에 추가해주어야 한다.
- Java Config기준으로 WebMvcConfigurerAdapter를 상속받은 클래스(Servlet설정)에서
configureMessageConverters Method를 override해서 처리한다.
4. Spring Servlet설정(3번에 명시한 WebMvcConfigurerAdapter) 클래스에 @EnableSwagger를 추가해준다.
- 여기서 주의할 점은, ComponentScan등으로 Controller 어노테이션 등 문서화할 REST API들을 찾아 Bean으로 만들어주는 작업이 선행되어 있어야 한다는 것
5. 확인은 로컬 톰캣 기본 설정 기준으로 http://localhost:8080/{어플리케이션ROOT Path}/api-docs에서 한다.
[Swagger UI 설정 (https://github.com/wordnik/swagger-ui) - GitHub에서 생략되어 있는 설명들이 너무나도 많다.-_-]
1. git bash등을 이용해서 https://github.com/wordnik/swagger-ui.git를 clone으로 로컬에 땡겨온 후에, 웹 프로젝트에 추가해준다.
- 땡겨오게되면, dist라는 폴더만 있는데 그 안에 있는 내용들만 WEB-INF/views/swagger-ui 폴더를 생성하여 넣어주도록 한다.
2. Spring Servlet설정에서 InternalResourceViewResolver를 생성해주고, 리소스 경로를 루트에서 사용할 수 있도록 설정해준다.
(가장 중요한 설정이며, 뭔가 잘 안되면 무조건 이 설정에서 경로가 잘못지정된 것이다. /를 넣느냐 마느냐가 매우 중요한 역할을 함..--)
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("**")
.addResourceLocations("/WEB-INF/views/swagger-ui/")
.setCachePeriod(0);
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
3. WEB-INF/views/swagger-ui/index.html파일을 index.jsp로 바꾸어준다.
- 확장자만 바꾸면 안되고, jsp상단에 항상 포함되어 있는,
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> 도 같이 넣어준다.
4. ModelAndView형식의 컨트롤러를 하나 만들어서, index.jsp파일을 열도록 해준다.
@RequestMapping(value = "/ui")
public ModelAndView ui(ModelAndView mav) {
mav.setViewName("/swagger-ui/index");
return mav;
}
5. 확인
- http://localhost:8080/{Root Path}/ui
세팅은 여기까지가 완료이고, 더 연구해 보아야할 것들을 정리해보면..
1. UI상에 Parameter와 Response들이 표시가 되는데, @RequestParam이나 @RequestBody등을 사용하지 않고
Pojo로 받는 경우에는 해당 Pojo의 클래스명만 나오고, 클래스의 내부 variable들은 보이지 않는다.
2. 파라미터를 입력할 수 있는 Text Box에 1번처럼 @RequestParam, @RequestBody를 사용하지 않고, Pojo인 경우
아무것도 없는 비어있는 Text Box가 나온다. (1번이 해결되면 같이 해결될 문제인 것 같음)
현재 개발중인 어플리케이션이 파라미터는 Pojo로 받고, 리턴은 Map으로 하기 때문에,
뭔가 커스터마이징해야 원하는대로 사용할 수 있을 것 같다.
사용할 수 있는건, 현재 구현되어 있는 API가 어떤게 있다라는 정도...
고생한 거에 비해 소득이 별로 없으니, 커스터마이징을 해봐야겠다.
[커스터마이징 결과]
UI에 보이는 Parameter DataType부분을 Pojo에 선언된 변수들을 Reflection으로 열어서, Json String으로 만들어 뿌려주는 것은 성공
하지만, 이 작업에는 SwaggerSpringMvcPlugin의 옵션중 customAnnotationReaders옵션을 이용하여
Reader를 직접 구현하여 넣어주어야 하며, 기존에 등록되어 있던 Reader가 고스란히 동작하는 바람에, 두번 처리가 되어
UI상에도 두줄로 표시되고 있었다.. ㅡㅡ;;
RequestParam이랑 RequestBody쓰면 암것도 안건드리고, 그냥되는건데
왜 Json문자열 앞에 파라미터명이 있고, 그 파라미터로 Json통 문자열이 들어와버리니 참 골치아픔..
결론은.. 여기에 맞게 사용하려면 Reader를 제거할 수 있는 옵션이 나오길 기다려야되는듯;;;