티스토리 뷰

프로그래밍

Spring MVC + Swagger2

ReturnToHome 2019. 6. 23. 16:24

REST API 를 구성 할 시, 테스트 방법은 다양하다. 내 경우는 IntelliJ 를 사용할 시에는 request.http 를 사용하고, Tool 을 사용할때는 POST MAN이나, 브라우저에서 ARC, POST MAN 플러그인을 사용하기도 한다. 하지만 이는 나 혼자만의 테스트를 위한 방법에 불과하며, 여럿이 함께하고자 할때, 각각 위와 같은 방법으로 데이터를 셋팅하고, 확인하고 하는 것은 여간 귀찮은 일이 아닐 것이다. 그렇기에 찾아본 것이 Swagger.

사실 이 Swagger 자체는 알고지낸 지는 꽤 되었지만, 실제로 샘플 마저 구성해본적은 없었다.

... 라고 위에 주절주절 쓰려고 했지만, 여기까지 오신 분들은 왠만해서 왜 왔는지 아시리라 생각하고 바로 샘플 코드로 들어가고자 한다.

 

 

1. 환경: Spring MVC (version 5.1.1) + Swagger2 (version 2.6.1)

 

2. 필요 라이브러리

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.6.1</version>
    </dependency>

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.6.1</version>
    </dependency>

Swagger 사용을 위해서는 구현체인 springfox-swagger2 가 필요하다고 하며, 또 가장 중요한 (사용목적이라해도 과언이 아닌) UI 적으로 확인을 위해서는 springfox-swagger-ui 이렇게 2개의 라이브러리가 필요하다.

 

3. 필요 클래스파일 생성

-> Swagger 사용 시에는 Docket Bean 을 품고있는 설정 클래스 1개가 기본으로 필요하다. Spring Boot 에서는 이 기본적인 설정파일 1개로 Swagger 와 Swagger UI 를 함께 사용가능하지만, Spring MVC 의 경우 Swagger UI 를 위한 별도의 설정이 필요하다.

이는, Swagger UI 를 ResourceHandler 에 수동으로 등록해야 하는 작업인데, Spring Boot 에서는 이를 자동으로 설정해주지만 Spring MVC 에서는 그렇지 않기 때문이라고 한다.

이 별도의 설정은 따로 클래스를 생성하여 작업할 수도 있지만, 편의상 Docket Bean 을 설정 한 1개의 Swagger Config 클래스 파일에 선언, 명시하였다.

  • SwaggerConfig
    • Swagger 기본 설정을 담당하는 Docket Bean 을 품고있는 클래스이며, Swagger 관련 설정은 모두 이 Bean 에 중심을 두고 있다고 한다. 그리고 위에 언급했듯이 Spring Boot 와는 다르게 Swagger UI 의 ResourceHanlder 등록을 위해 WebMvcConfigurationSupport 클래스를 상속받은 후, addResourceHandlers 메소드를 오버라이드하여 Swagger UI 를 ResourceHandler 로 등록해주어야 한다.
    • 여기서 한 가지 체크하고 넘어가야 할 것은 ResourceHandler 등록을 위한 방법인데 2가지 방법은 아래와 같다.
      • @EnableWebMvc 어노테이션 설정 + WebMvcConfigurerAdapter 상속
      • WebMvcConfigurationSupport 상속
    • 위 2가지 방법이 있는데 내 경우, 본문 상단의 환경에 명시한 것 처럼 Spring 5.1.1 을 사용 중이다. 그리고 Spring 5 에서는 WebMvcConfigurerAdapter 클래스가 deprecated 되었으므로 WebMvcConfigurationSupport 를 사용한 것이다. 만약 Spring 5 이하 버전이라면 어떤 방법으로 해도 상관 없을 것 같다.
    • 실제로 Spring 4.2.5 버전에서 테스트 결과 2가지 방법 모두 정상적으로 잘 동작하는 것을 확인하였다.
    • 아래는 deprecated 에 관한 내용을 예전에 검색해 놓은 내용..
    • Deprecated.  as of 5.0 WebMvcConfigurer has default methods (made possible by a Java 8 baseline) and can be implemented directly without the need for this adapter
    • Java 8 에서 default method 가 생기면서 추상클래스인 WebMvcConfigurerAdapter 의 메소드들을 구현하지 않아도 된다.. 는 뜻이라고 한다.
@Configuration
@EnableSwagger2
@ComponentScan("com.app.api")
public class SwaggerConfig extends WebMvcConfigurationSupport {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo())
                .useDefaultResponseMessages(false);
    }
    
    /** API Info */
    private ApiInfo apiInfo() {
        ApiInfo apiInfo = new ApiInfo("Swagger Sample", "APIs Sample", "Sample Doc 0.1v", "", "Author Name", "This sentence will be display.", "/");
        return apiInfo;
    }
    
    /** Swagger UI 를 Resource Handler 에 등록 */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

 

위 소스는 Swagger 사용을 위한 기본 소스이며 아래와 같이 용도에 따라 변경하여 사용하면 된다고 한다.

 

RequestHandlerSelectors.any() -> 전체 문서의 API 화

RequestHandlerSelectors.basePackage("com.app.api") -> 지정된 패키지만 API 화

PathSelectors.any() -> 모든 URL 패턴에 대해 수행

PathSelectors.ant("/apis/*") -> 특정 경로에 있는 컨트롤러만 포함

 

** -> 여기서 내 경우는, RequestHandlerSelectors.basePackage("com.app.api") 로 지정을 해주었지만, Swagger UI 에서 해당 패키지에 있는 컨트롤러가 노출되지 않았다. 그래서 클래스 상단의 @ComponentScan 을 통해 직접 명시를 하고 난 이후에야 노출이 되었는데.. 이는 context 의 component scan 과 설정이 맞지 않아서 그런 것인지.. 조금 더 확인이 필요할 것 같다. (servlet-context 에는 이미 com.app.api 패키지에 대해 scan 하도록 되어있다.. 아마 WebMvcConfigurationSupport 를 상속받아서 그런가.. 혹시 아시는 분은 댓글 부탁드립니다.. (_ _)...)

 

또한, 화면에 별도의 커스텀 정보를 노출하기 위해서는 API Info를 추가해주면 된다.

 

그리고 이제 샘플로 Controller 하나를 생성하여, GET 메소드 1개를 기본으로 등록하여 보았다.

@RestController
@RequestMapping("/apis")
@Api(value="APIs")
public class SampleController {

	@ApiOperation(value="[GET] Method")
	@GetMapping("/")
	public @ResponseBody ArticleVO sampleGet(HttpServletRequest request, @RequestParam("srl") String srl) {
		ArticleVO vo = new ArticleVO();
		vo.setArticleSrl(1);
		vo.setSubject("title");
		vo.setContent("content");
		
		return vo;
	}
}

 

위와 같이 모든 기본 설정을 끝내고 서버를 띄운 후 http://localhost/swagger-ui.html 로 접속하게 되면 아래와 같은 화면을 볼 수 있다.

 

 

아무것도 클릭하지 않은 첫번째 화면에서는 본인이 설정한 패키지 or 프로젝트에 REST API 로 등록된 컨트롤러 (만약 더 있다면 n 개만큼 노출이 될 것이다) 와 함께 API Info 로 등록해주었던 내용을 볼 수 있을 것이다.

 

이제 sample-controller 를 클릭하면 SampleController 에 등록된 메소드 목록이 노출된다.

 

그리고 다시 해당 메소드를 클릭하게 되면, 아래와 같이 상세 정보를 확인 할 수 있다.

선택한 Method 를 호출하였을 시 받게 되는 결과값이 예시로 나와 있으며, 하단에는 해당 Method 에서 제공하는 Parameter 정보가 파라미터명과 Type 까지 상세히 표시되고 있으며 이를 입력하여 Try it out! 으로 실제로 서비스 호출을 할 수 있다.

 

만약 (required) 인 srl 파라미터를 입력하지 않고 Try it out! 을 클릭하게 된다면 위 사진 처럼 수행이 되지 않는다.

 

아래는 임의값 1을 던져 실제로 서비스가 호출 된 결과를 나타내는 화면이다.

Controller 에서 하드코딩으로 데이터를 셋팅해 놓았기 때문에 articleSrl, subject, content 만 셋팅되어져 내려오지만,

실제로 로직이 있을 경우 정상적으로 노출 되는 것을 확인 할 수 있다.

 

 

* 추가적으로 @WebMvcConfigurationSupport 에 대해 적어보자면..

Spring Boot 의 경우 @EnableWebMvc 을 명시하게 되면 WebMvcConfigurationSupport 가 자동으로 빈으로 등록되기에 Spring boot Web 기본 설정을 잡아주는 WebMvcAutoConfiguration 이 동작하지 않는다고 한다. 이유는 이 WebMvcAutoConfiguration 에 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 라고 명시되어 있기 때문이라고 한다. (WebMvcConfigurationSupport 클래스가 Bean 으로 등록되어있지 않을 경우에만 WebMvcAutoConfiguration 가 동작하라는 뜻이라고 한다.

WebMvcAutoConfiguration 이 하는 Spring boot Web 기본 설정은 Spring MVC 에서의 <mvc:annotation-driven /> 과 같다고 한다. (RequestMappingHandler,RequestMappingHandlerAdapter,ExceptionHandlerExceptionResolver 등 Web 에 필요한 Bean 들을 자동으로 설정하주는..)

그렇기에 Spring boot Web 의 기본 설정이 필요없고 커스텀한 설정을 하고 싶을 때에만 @EnableWebMvc 를 명시하고 그렇지 않을 경우에는 자동설정 + WebMvcConfigurerAdapter 를 사용하면 된다고 한다. 

* 위 내용들은 모두 검색에 기반하여 개인적인 생각으로 정리한 내용입니다..!

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함