반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- javascript
- yona
- spring
- popup
- centos7
- node.js
- Next.js
- SpringBoot
- console
- config
- Java
- submit
- mysql
- spring3
- Eclipse
- PM2
- post
- security
- MSsql
- git
- jenkins
- ajax
- MariaDB
- rocky9
- docker
- nodejs
- mybatis
- jquery
- Maven
- NextJS
Archives
- Today
- Total
ふたりで
springboot+swagger+config 본문
728x90
반응형
SMALL
springboot 후로잭트에 swagger를 설정 하는 방법에 대해 정리 해본다...
먼저 아래와 같이 Maven 설정.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
1. SwaggerConfig.java 작성.
swagger를 사용하기 위해 springboot 프로잭트에 설정을 한다.
package com.graykang.test.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.bind.annotation.RequestMethod;
import com.graykang.test.supplierorder.common.model.RestException;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.DocExpansion;
import springfox.documentation.swagger.web.ModelRendering;
import springfox.documentation.swagger.web.OperationsSorter;
import springfox.documentation.swagger.web.TagsSorter;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Profile({"local","dev"})//개발과 로컬에서만 API UI가 보여 지게 설정.
@Configuration
@EnableSwagger2
public class SwaggerConfig {
private String version;
private String title;
@SuppressWarnings("unchecked")
@Bean
public Docket apiDefault() {//기본 설정.
version = "Default";
title = "API " + version;
@SuppressWarnings("rawtypes")
List global = new ArrayList();
global.add(new ParameterBuilder().name("Authorization").
description("AccessToken").parameterType("header").
required(false).modelRef(new ModelRef("string")).build());
return new Docket(DocumentationType.SWAGGER_2)
.globalOperationParameters(global)/*Authentication header 처리를 api-version별 사용하기 위해 global 사용*/
.useDefaultResponseMessages(false)
.groupName(version)
.select()
.apis(RequestHandlerSelectors.basePackage(""))
.paths(PathSelectors.ant("/Default/api/**"))
.build()
.apiInfo(apiDefaultInfo(title, version));
}
@SuppressWarnings("unchecked")
@Bean
public Docket apiV1() {
version = "V1";
title = "API " + version;
@SuppressWarnings("rawtypes")
List global = new ArrayList();
global.add(new ParameterBuilder().name("Authorization").
description("AccessToken").parameterType("header").
required(false).modelRef(new ModelRef("string")).build());
return new Docket(DocumentationType.SWAGGER_2)
.globalOperationParameters(global)/*Authentication header 처리를 api-version별 사용하기 위해 global 사용*/
.useDefaultResponseMessages(false)
.groupName(version)
.select()
.apis(RequestHandlerSelectors.basePackage("com.graykang.test"))
.paths(PathSelectors.ant("/v1/api/**"))
.build()
.apiInfo(apiInfoV1(title, version));
}
/**
* v2용 API는 토큰 인증대신 파라메터값으로 자체 인증 함으로 Authentication 로직 주석 처리.
* @return
*/
@Bean
public Docket apiV2() {
version = "V2";
title = "API " + version;
// @SuppressWarnings("rawtypes")
// List global = new ArrayList();
// global.add(new ParameterBuilder().name("Authorization").
// description("AccessToken").parameterType("header").
// required(false).modelRef(new ModelRef("string")).build());
return new Docket(DocumentationType.SWAGGER_2)
// .globalOperationParameters(global)/*Authentication header 처리를 api-version별 사용하기 위해 global 사용*/
.useDefaultResponseMessages(false)
.groupName(version)
.select()
.apis(RequestHandlerSelectors.basePackage("com.graykang.test.v2api"))
.paths(PathSelectors.ant("/v2/api/**"))
.build()
.apiInfo(apiInfoMgr(title, version));
}
private ApiInfo apiDefaultInfo(String title, String version) {
return new ApiInfo(
title,
"Swagger-Default",
version,
"",
new Contact("", "", "tenpest@naver.com"),
"",
"",
new ArrayList<>());
}
private ApiInfo apiInfoV1(String title, String version) {
return new ApiInfo(
title,
"Swagger로 생성한 API Docs\n 1.cryptoTest서비스는 authenticate를 테스트할때 userid/password암호화를 위해 사용한다.\n 2.authenticate를 호출해 Token발급\n 3.발급받은 Token을 Header값[Authorization]에 입력하여 조회용API를 호출 한다.",
version,
"",
new Contact("", "", "graykang@naver.com"),
"",
"graykang.tistory.com",
new ArrayList<>()
);
}
private ApiInfo apiInfoV2(String title, String version) {
// return new ApiInfo(
// title,
// "Swagger로 생성한 API Docs\n MGR에서 상품발주서 전송시 사용.",
// version,
// "www.graykang.kr",
// new Contact("Contact Me", "www.graykang.kr", "tenpest@naver.com"),
// "Licenses",
//
// "graykang.tistory.com",
//
// new ArrayList<>());
return new ApiInfo(
title,
"Swagger로 생성한 API Docs\n V2 데이터 전송시 사용.",
version,
"",
new Contact("", "", "graykang@naver.com"),
"",
"",
new ArrayList<>()
);
}
@Bean
UiConfiguration uiConfig() {
return UiConfigurationBuilder.builder()
.deepLinking(false)
.displayOperationId(false)
.defaultModelsExpandDepth(-1)
.defaultModelExpandDepth(1)
.defaultModelRendering(ModelRendering.EXAMPLE)
.displayRequestDuration(false)
.docExpansion(DocExpansion.NONE)
.filter(false)
.maxDisplayedTags(null)
.operationsSorter(OperationsSorter.METHOD)
.showExtensions(false)
.tagsSorter(TagsSorter.ALPHA)
.supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
.validatorUrl(null)
.build();
}
}
2. SwaggerController.java 작성
swagger API document UI 용 페이지 전환용 컨트롤러...
package com.graykang.test.common.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class SwaggerController {
@RequestMapping(value = "/swaggerV1", method = RequestMethod.GET)
public String swaggerCallV1(Model model) {
System.out.println("swaggerv1");
return "api-v1";
}
@RequestMapping(value = "/swaggerapilocalV2", method = RequestMethod.GET)
public String swaggerCallLocalV2(Model model) {
System.out.println("swaggerv2");
return "api-localv2";
}
}
3. 컨트롤러에서 전환해줄 jsp 작성
3-1. api-v1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Biz Swagger UI</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/swagger/css/swagger-ui.css" >
<link rel="icon" type="image/png" href="${pageContext.request.contextPath}/swagger/img/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="${pageContext.request.contextPath}/swagger/img/favicon-16x16.png" sizes="16x16" />
<script src="${pageContext.request.contextPath}/swagger/js/swagger-ui-bundle.js"> </script>
<script src="${pageContext.request.contextPath}/swagger/js/swagger-ui-standalone-preset.js"> </script>
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script>
function getContextPath() {
var hostIndex = location.href.indexOf( location.host ) + location.host.length;
return location.href.substring( hostIndex, location.href.indexOf('/', hostIndex + 1) );
}
window.onload = function() {
const hostIndex = location.href.indexOf( location.host ) + location.host.length;
const path = location.href.substring( hostIndex, location.href.indexOf('/', hostIndex + 1) );
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "${pageContext.request.contextPath}/v2/api-docs?group=V1",
dom_id: '#swagger-ui',
deepLinking: true,
defaultModelsExpandDepth: -1, // <-------
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset.slice(1)
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>
3-2. api-localv2.jap
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MGR Swagger UI</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/swagger/css/swagger-ui.css" >
<link rel="icon" type="image/png" href="${pageContext.request.contextPath}/swagger/img/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="${pageContext.request.contextPath}/swagger/img/favicon-16x16.png" sizes="16x16" />
<script src="${pageContext.request.contextPath}/swagger/js/swagger-ui-bundle.js"> </script>
<script src="${pageContext.request.contextPath}/swagger/js/swagger-ui-standalone-preset.js"> </script>
<script src="${pageContext.request.contextPath}/swagger/js/jquery-3.3.1.min.js"> </script>
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script>
function getContextPath() {
var hostIndex = location.href.indexOf( location.host ) + location.host.length;
return location.href.substring( hostIndex, location.href.indexOf('/', hostIndex + 1) );
}
window.onload = function() {
//const hostIndex = location.href.indexOf( location.host ) + location.host.length;
//const path = location.href.substring( hostIndex, location.href.indexOf('/', hostIndex + 1) );
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "${pageContext.request.contextPath}/v2/api-docs?group=mgr",
dom_id: '#swagger-ui',
deepLinking: true,
defaultModelsExpandDepth: -1, // <-------
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>
4. 실사용되는 컨트롤러 예시
아래의 컨트롤러 소스 코드는 분기시킨 V2 기준 이다.
package com.graykang.test.v2api.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.graykang.test.common.model.JwtRequest;
import com.graykang.test.common.model.PmTestRequestVO;
import com.graykang.test.common.model.PmVO;
import com.graykang.test.common.model.RestException;
import com.graykang.test.common.util.CustomCollectionValidator;
import com.graykang.test.common.util.SecureUtil;
import com.graykang.test.v2api.model.MartCouncilInfoVO;
import com.graykang.test.v2api.model.OrderListByMartCouncilVO;
import com.graykang.test.v2api.model.OrderListMartCouncilResultVO;
import com.graykang.test.v2api.model.ResultVO;
import com.graykang.test.v2api.model.SupplierOrderListPutVO;
import com.graykang.test.v2api.model.SupplierOrderListPutVO2;
import com.graykang.test.v2api.service.V2ApitService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@Api(tags = {"1. MGR API Service"})
@CrossOrigin
@RestController
@RequestMapping(value = "/v2/api")
public class V2APIController {
private static Logger logger = LoggerFactory.getLogger(V2APIController.class);
@Autowired
CustomCollectionValidator customCollectionValidator;
@Autowired
V2ApiService v2ApiService;
/**
* @param securityKey
* @return
* @throws Exception
*/
@ApiOperation(value = "4.테스트 데이터 리스트 반환")
@ApiImplicitParams({
@ApiImplicitParam(name = "securityKey", value="", required=true, dataType="String", paramType="query", defaultValue="", example="")
})
@ApiResponses({
@ApiResponse(code=200,message="OK", response= TeatDataResultVO.class),//반환되는VO
@ApiResponse(code=401,message="Unauthorization", response= RestException.class),//예외처리VO
@ApiResponse(code=403,message="Forbidden", response= RestException.class),
@ApiResponse(code=400,message="Bad Request", response= RestException.class),
@ApiResponse(code=500,message="ServerError", response= RestException.class)
})
@PostMapping("/getTestDataList")
public ResponseEntity<?> getListByTestData(@RequestParam("securityKey") String securityKey) throws Exception{
TestDataResultVO result = new TestDataResultVO();
authVO authResult = SecureUtil.decodeAuth(securityKey);
if(authResult != null) {
List<DataMainVO> items = v2ApiService.getTestListByTestData(authResult.getKey());
result.setTotal(items.size());
result.setItems(items);
}else {
logger.error("Unauthorization:securityKey값이 올바르지 않습니다");
throw new IllegalArgumentException("securityKey값이 올바르지 않습니다");
}
return ResponseEntity.ok(result);
}
}
5. 위의 컨트롤러를 통해 반환되는 TestDataResultVO.java
package com.graykang.test.v2api.model;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel
public class TestDataResultVO{
@ApiModelProperty(value="int() 전체 건수")
private int total;
private List<DataMainVO> items;
public List<DataMainVO> getItems() {
return items;
}
public void setItems(List<DataMainVO> items) {
this.items = items;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
}
6. 위의 TestDataResultVO.java 내에 정의된 List<DataMainVO> items 즉 DataMainVO.java는 생략...
728x90
반응형
LIST
'Spring' 카테고리의 다른 글
springboot+security session timeout config (0) | 2022.06.23 |
---|---|
spring tags + application.properties 값 참조 하기 (0) | 2022.04.28 |
spring(springboot) simple POST request (API call) (0) | 2022.03.15 |
springboot + security tags를 사용한 menu권한 처리 및 수동 인증(강제로그인). (0) | 2021.12.28 |
springboot+sitemesh 설정. (0) | 2021.12.20 |
Comments