Swagger와 웹 프로젝트 연동하기

프로젝트 생성

  • File - New - Maven Project으로 생성
  • architype: webapp
  • Group Id: org.edwith.webbe
  • Artifact Id: calculator

Swagger 연동

1) pom.xml에 의존성 추가

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.edwith.webbe</groupId>
	<artifactId>calculator</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>calculator Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<!-- Eclipse에서는 web.xml 파일을 작성하지 않고, Java Config를 사용할 때 failOnMissingWebXml를 
		false로 설정합니다. -->
	<!-- spring 버전은 5.0.2.RELEASE버전을 사용합니다. 2020/02/03일 기준 최신버전 -->
	<properties>
		<failOnMissingWebXml>false</failOnMissingWebXml>
		<spring.version>5.2.3.RELEASE</spring.version>
	</properties>
	<dependencies>
		<!-- servlet-api이다. tomcat에 배포될 경우엔 사용되지 않도록 하기 위해서 scope를 provided로 설정하였다. -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>

		<!-- jsp-api이다. tomcat에 배포될 경우엔 사용되지 않도록 하기 위해서 scope를 provided로 설정하였다. -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.2-b02</version>
			<scope>provided</scope>
		</dependency>

		<!-- jstl은 tomcat이 기본 지원하지 않는다. 그렇기 때문에 tomcat에도 배포가 되야 한다. -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!-- spring webmvc에 대한 의존성을 추가한다. spring webmvc에 대한 의존성을 추가하게 되면 spring-web, 
			spring-core등이 자동으로 의존성이 추가된다. -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- RestController의 json 변환을 위해 필요함 -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.9.8</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.8</version>
		</dependency>

		<!-- java 9 이상에서 추가해줘야 합니다. @PostConstruct 등을 사용하려면 필요함 -->
		<dependency>
			<groupId>javax.annotation</groupId>
			<artifactId>javax.annotation-api</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>


		<!-- swagger2 의존성 추가 Swagger 사용을 위해서는 구현체인 springfox-swagger2 가 필요하며, 또 
			가장 중요한 (사용목적이라해도 과언이 아닌) UI 적으로 확인을 위해서는 springfox-swagger-ui 이렇게 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>

	</dependencies>
	<build>
		<finalName>calculator</finalName>
		<plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
        </plugins>
	</build>
</project>

2) WebAppInitializer 클래스 생성

  • web.xml파일 대신 WebApplicationInitializer를 사용
  • src/main에 java 폴더 생성
  • org.edwith.webbe.calculator.config 패키지 생성
  • 패키지 내에 WebAppInitializer 클래스가 AbstractAnnotationConfigDispatcherServletInitializer을 상속받도록 설정 후 생성
package org.edwith.webbe.calculator.config;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.*;

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
	// Spring 기본 Config 클래스 지정
	// ApplicationConfig.class 사용
	@Override
	protected Class<?>[] getRootConfigClasses() {
		return Class<?>[] {ApplicationConfig.class};
	}

	//Spring MVC Config 클래스 지정
	// MvcConfig.class 사용
	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class<?>[] {MvcConfig.class};
	}
	
	// DispatcherServlet이 동작할 맵핑 정보 설정
	// "/"으로 설정해 모든 요청을 DispatcherServlet이 처리하도록 함
	@Override
	protected String[] getServletMappings() {
		return new String[] {"/"};
	}
	
	// 인코딩 필터 설정
	@Override
	protected Filter[] getServletFilters() {
		CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
		encodingFilter.setEncoding("UTF-8");
		
		return new Filter[] {encodingFilter};
	}
}

3) ApplicationConfig 클래스 생성

package org.edwith.webbe.calculator.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages= {"org.edwith.webbe.calculator.service"})
public class ApplicationConfig {

}

4) MVCConfig 클래스 생성

  • Swagger 어노테이션 등록
  • Docket Bean 등록

MvcConfig.java

package org.edwith.webbe.calculator.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableWebMvc
@EnableSwagger2
@ComponentScan(basePackages = { "org.edwith.webbe.calculator.controller" })
public class MvcConfig implements WebMvcConfigurer {

	// DefaultServlet에 대한 설정
	// DispatcherServlet이 처리하지 못하는 URL은 DefaultServlet이 처리
	// 자동 생성된 Swaager 페이지를 보기 위함
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	/*
	 * Swagger 사용 시에는 Docket Bean 을 품고있는 설정 클래스 1개가 기본으로 필요하다. Spring Boot 에서는 이
	 * 기본적인 설정파일 1개로 Swagger 와 Swagger UI 를 함께 사용가능하지만, Spring MVC 의 경우 Swagger UI 를
	 * 위한 별도의 설정이 필요하다. 이는, Swagger UI 를 ResourceHandler 에 수동으로 등록해야 하는 작업인데, Spring
	 * Boot 에서는 이를 자동으로 설정해주지만 Spring MVC 에서는 그렇지 않기 때문이다.
	 */
	@Bean
	public Docket api() {
		return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()) // // 현재																				// 할당된 모든 URL 리스트를
																									// 추출
				.paths(PathSelectors.ant("/api/**"))// PathSelectors.any() 를 할경우 모든 경로가 다 사용된다. RestController가 아닌 것 까지
													// 사용된다.
				.build().apiInfo(apiInfo()).useDefaultResponseMessages(false);
	}

	//API Info
	private ApiInfo apiInfo() {
		Contact contact = new Contact("MinKyeong Kim", "https://www.edwith.org", "[email protected]");
		ApiInfo apiInfo = new ApiInfo("Swagger Sample", "APIs Sample", "Sample Doc 0.1v", "", contact,
				"This sentence will be display.", "/");
		return apiInfo;
	}
}

5) 서비스 클래스 생성

  • .service 패키지 생성 후 클래스 생성
    CalculatorService.java
package org.edwith.webbe.calculator.service;

import org.springframework.stereotype.Service;

@Service
public class CalculatorService {
	public int plus(int value1, int value2) {
		return value1+value2;
	}
	public int minus(int value1, int value2) {
		return value1-value2;
	}
}

6) DTO 클래스 생성

  • .dto 패키지 생성 후 클래스 생성
    CalculatorResult.java
package org.edwith.webbe.calculator.dto;

public class CalculatorResult {
	public static final String PLUS_OPERATION = "+";
	public static final String MINUS_OPERATION = "-";
	public static final String MULTIPLE_OPERATION = "*";
	public static final String DIVIDE_OPERATION = "/";
	
	private int value1;
	private int value2;
	private int result;
	private String operation;
	public int getValue1() {
		return value1;
	}
	public void setValue1(int value1) {
		this.value1 = value1;
	}
	public int getValue2() {
		return value2;
	}
	public void setValue2(int value2) {
		this.value2 = value2;
	}
	public int getResult() {
		return result;
	}
	public void setResult(int result) {
		this.result = result;
	}
	public String getOperation() {
		return operation;
	}
	public void setOperation(String operation) {
		this.operation = operation;
	}	
}

7) Controller 클래스 생성

다음 명세에 맞게 매핑

  • controller.api 패키지 생성 후 클래스 생성

CalculatorApiController.java

package org.edwith.webbe.calculator.controller.api;

import org.edwith.webbe.calculator.dto.CalculatorResult;
import org.edwith.webbe.calculator.service.CalculatorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@RestController //응답 결과를 json으로 보내기 위함
@RequestMapping(path="api/calculator") //공통적으로 path 지정(기본 path로 받아들여짐)
public class CalculatorApiController {
	@Autowired
	private CalculatorService calculatorService;
	
	//Swagger가 제공하고 있는 어노테이션
	//간단한 설명을 적어줄 때 사용
	@ApiOperation(value = "덧셈 구하기")
	
	// Response Message에 대한 설명
    @ApiResponses({  
            @ApiResponse(code = 200, message = "OK"),
            @ApiResponse(code = 500, message = "Exception")
    })
	
	@GetMapping("/plus")
	public CalculatorResult plus(@RequestParam("value1") int value1, @RequestParam("value2") int value2) {
		CalculatorResult calculatorResult = new CalculatorResult();
		calculatorResult.setValue1(value1);
		calculatorResult.setValue2(value2);
		calculatorResult.setOperation(CalculatorResult.PLUS_OPERATION);
		calculatorResult.setResult(calculatorService.plus(value1, value2));
		
		return calculatorResult;
	}
	
	@GetMapping("/minus")
	public CalculatorResult minus(@RequestParam("value1") int value1, @RequestParam("value2") int value2) {
		CalculatorResult calculatorResult = new CalculatorResult();
		calculatorResult.setValue1(value1);
		calculatorResult.setValue2(value2);
		calculatorResult.setOperation(CalculatorResult.MINUS_OPERATION);
		calculatorResult.setResult(calculatorService.minus(value1, value2));
		
		return calculatorResult;
	}
}

8) Swagger UI 연동 완료

http://localhost:8080/calculator/swagger-ui.html# URL으로 접근하면 ApiController에서 작성한 operation들을 테스트할 수 있다!

  • swagger 메인 화면

  • 테스트 해본 화면, 구현해놓은 함수에 따라 작동함

좋은 웹페이지 즐겨찾기