@@ -1,9 +1,9 @@
package org.jeecg.modules.openapi.controller ;
import com.alibaba.fastjson.JSONObject ;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper ;
import com.baomidou.mybatisplus.core.metadata.IPage ;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page ;
import com.fasterxml.classmate.ResolvedType ;
import com.fasterxml.classmate.TypeResolver ;
import com.google.common.collect.Lists ;
import org.jeecg.common.api.vo.Result ;
@@ -20,21 +20,17 @@ import org.jeecg.modules.openapi.service.OpenApiAuthService;
import org.jeecg.modules.openapi.service.OpenApiHeaderService ;
import org.jeecg.modules.openapi.service.OpenApiParamService ;
import org.jeecg.modules.openapi.service.OpenApiService ;
import org.jeecg.modules.openapi.swagger.* ;
import org.jeecg.modules.system.entity.SysUser ;
import org.jeecg.modules.system.service.ISysUserService ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.boot.CommandLineRunner ;
import org.springframework.http.HttpEntity ;
import org.springframework.http.HttpHeaders ;
import org.springframework.http.HttpMethod ;
import org.springframework.util.CollectionUtils ;
import org.springframework.util.StringUtils ;
import org.springframework.web.bind.annotation.* ;
import org.springframework.web.client.RestTemplate ;
import springfox.documentation.schema.Model ;
import springfox.documentation.schema.ModelProperty ;
import springfox.documentation.schema.ModelRef ;
import springfox.documentation.schema.ModelReference ;
import springfox.documentation.service.* ;
import springfox.documentation.spring.web.DocumentationCache ;
import javax.servlet.http.HttpServletRequest ;
@@ -45,7 +41,7 @@ import java.util.*;
*/
@RestController
@RequestMapping ( " /openapi " )
public class OpenApiController extends JeecgController < OpenApi , OpenApiService > implements CommandLineRunner {
public class OpenApiController extends JeecgController < OpenApi , OpenApiService > {
@Autowired
private RestTemplate restTemplate ;
@@ -201,138 +197,184 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
return restTemplate . exchange ( url , HttpMethod . resolve ( method ) , httpEntity , Result . class , request . getParameterMap ( ) ) . getBody ( ) ;
}
@GetMapping ( " /call/add " )
public void addS wagger( ) {
Documentation documentation = documentationCache . documentationByGroup ( " default " ) ;
@GetMapping ( " /json " )
public SwaggerModel s waggerModel ( ) {
List < ApiListing > apis = new ArrayList < > ( ) ;
SwaggerModel swaggerModel = new SwaggerModel ( ) ;
swaggerModel . setSwagger ( " 2.0 " ) ;
swaggerModel . setInfo ( swaggerInfo ( ) ) ;
swaggerModel . setHost ( " jeecg.com " ) ;
swaggerModel . setBasePath ( " /jeecg-boot " ) ;
swaggerModel . setSchemes ( Lists . newArrayList ( " http " , " https " ) ) ;
Set < String > produces = new HashSet < > ( ) ;
produces . add ( " application/json " ) ;
Set < String > consumes = new HashSet < > ( ) ;
consumes . add ( " application/json " ) ;
SwaggerTag swaggerTag = new SwaggerTag ( ) ;
swaggerTag . setName ( " openapi " ) ;
swaggerModel . setTags ( Lists . newArrayList ( swaggerTag ) ) ;
Set < String > tags = new HashSet < > ( ) ;
Tag tag = new Tag ( " openapi " , " openapi " ) ;
tags . add ( " openapi " ) ;
Set < Tag > apiTags = new HashSet < > ( ) ;
apiTags . add ( tag ) ;
documentation . getTags ( ) . add ( tag ) ;
pathsAndDefinitions ( swaggerModel ) ;
Model resultModel = documentation . getApiListings ( ) . get ( " login-controller " ) . get ( 0 ) . getModels ( ) . get ( " 接口返回对象«JSONObject» " ) ;
return swaggerModel ;
}
ModelRef stringModelRef = new ModelRef ( " string " ) ;
private void pathsAndDefinitions ( SwaggerModel swaggerModel ) {
Map < String , Map < String , SwaggerOperation > > paths = new HashMap < > ( ) ;
Map < String , SwaggerDefinition > definitions = new HashMap < > ( ) ;
List < OpenApi > openapis = service . list ( ) ;
for ( OpenApi openApi : openapis ) {
Map < String , SwaggerOperation > operations = new HashMap < > ( ) ;
SwaggerOperation operation = new SwaggerOperation ( ) ;
operation . setTags ( Lists . newArrayList ( " openapi " ) ) ;
operation . setSummary ( openApi . getName ( ) ) ;
operation . setDescription ( openApi . getName ( ) ) ;
operation . setOperationId ( openApi . getRequestUrl ( ) + " Using " + openApi . getRequestMethod ( ) ) ;
operation . setProduces ( Lists . newArrayList ( " application/json " ) ) ;
parameters ( operation , openApi ) ;
ResolvedType stringResolvedType = typeResolver . resolve ( String . class ) ;
// body入参
if ( StringUtils . hasText ( openApi . getBody ( ) ) ) {
SwaggerDefinition definition = new SwaggerDefinition ( ) ;
definition . setType ( " object " ) ;
Map < String , SwaggerDefinitionProperties > definitionProperties = new HashMap < > ( ) ;
definition . setProperties ( definitionProperties ) ;
JSONObject jsonObject = JSONObject . parseObject ( openApi . getBody ( ) ) ;
for ( Map . Entry < String , Object > properties : jsonObject . entrySet ( ) ) {
SwaggerDefinitionProperties swaggerDefinitionProperties = new SwaggerDefinitionProperties ( ) ;
swaggerDefinitionProperties . setType ( " string " ) ;
swaggerDefinitionProperties . setDescription ( properties . getValue ( ) + " " ) ;
definitionProperties . put ( properties . getKey ( ) , swaggerDefinitionProperties ) ;
}
// body的definition构建完成
definitions . put ( openApi . getRequestUrl ( ) + " Using " + openApi . getRequestMethod ( ) + " body " , definition ) ;
SwaggerOperationParameter bodyParameter = new SwaggerOperationParameter ( ) ;
bodyParameter . setDescription ( openApi . getName ( ) + " body " ) ;
bodyParameter . setIn ( " body " ) ;
bodyParameter . setName ( openApi . getName ( ) + " body " ) ;
bodyParameter . setRequired ( true ) ;
Map < String , String > bodySchema = new HashMap < > ( ) ;
bodySchema . put ( " $ref " , " #/definitions/ " + openApi . getRequestUrl ( ) + " Using " + openApi . getRequestMethod ( ) + " body " ) ;
bodyParameter . setSchema ( bodySchema ) ;
// 构建参数构建完成
operation . getParameters ( ) . add ( bodyParameter ) ;
}
// 响应
Map < String , SwaggerOperationResponse > responses = new HashMap < > ( ) ;
SwaggerOperationResponse resp200 = new SwaggerOperationResponse ( ) ;
resp200 . setDescription ( " OK " ) ;
Map < String , String > respSchema = new HashMap < > ( ) ;
respSchema . put ( " $ref " , " #/definitions/OpenApiResult " ) ;
resp200 . setSchema ( respSchema ) ;
responses . put ( " 200 " , resp200 ) ;
Map < String , String > emptySchema = new HashMap < > ( ) ;
SwaggerOperationResponse resp201 = new SwaggerOperationResponse ( ) ;
resp201 . setDescription ( " Created " ) ;
resp201 . setSchema ( emptySchema ) ;
responses . put ( " 201 " , resp201 ) ;
SwaggerOperationResponse resp401 = new SwaggerOperationResponse ( ) ;
resp401 . setDescription ( " Unauthorized " ) ;
resp401 . setSchema ( emptySchema ) ;
responses . put ( " 401 " , resp401 ) ;
SwaggerOperationResponse resp403 = new SwaggerOperationResponse ( ) ;
resp403 . setDescription ( " Forbidden " ) ;
resp403 . setSchema ( emptySchema ) ;
responses . put ( " 403 " , resp403 ) ;
SwaggerOperationResponse resp404 = new SwaggerOperationResponse ( ) ;
resp404 . setDescription ( " Not Found " ) ;
resp404 . setSchema ( emptySchema ) ;
responses . put ( " 404 " , resp404 ) ;
// 构建响应definition
SwaggerDefinition respDefinition = new SwaggerDefinition ( ) ;
respDefinition . setType ( " object " ) ;
Map < String , SwaggerDefinitionProperties > definitionProperties = new HashMap < > ( ) ;
respDefinition . setProperties ( definitionProperties ) ;
SwaggerDefinitionProperties codeProperties = new SwaggerDefinitionProperties ( ) ;
codeProperties . setType ( " integer " ) ;
codeProperties . setDescription ( " 返回代码 " ) ;
definitionProperties . put ( " code " , codeProperties ) ;
SwaggerDefinitionProperties messageProperties = new SwaggerDefinitionProperties ( ) ;
messageProperties . setType ( " string " ) ;
messageProperties . setDescription ( " 返回处理消息 " ) ;
definitionProperties . put ( " message " , messageProperties ) ;
SwaggerDefinitionProperties resultProperties = new SwaggerDefinitionProperties ( ) ;
resultProperties . setType ( " object " ) ;
resultProperties . setDescription ( " 返回数据对象 " ) ;
definitionProperties . put ( " result " , resultProperties ) ;
SwaggerDefinitionProperties successProperties = new SwaggerDefinitionProperties ( ) ;
successProperties . setType ( " boolean " ) ;
successProperties . setDescription ( " 成功标志 " ) ;
definitionProperties . put ( " success " , successProperties ) ;
SwaggerDefinitionProperties timestampProperties = new SwaggerDefinitionProperties ( ) ;
timestampProperties . setType ( " integer " ) ;
timestampProperties . setDescription ( " 时间戳 " ) ;
definitionProperties . put ( " timestamp " , timestampProperties ) ;
definitions . put ( " OpenApiResult " , respDefinition ) ;
HashMap < String , ModelProperty > propertyMap = new HashMap < > ( ) ;
ModelProperty modelProperty = new ModelProperty ( " abc " , stringResolvedType , " java.lang.String " , 0 , true , false , false , false , " 姓名 " , null , null , null , null , null , new ArrayList < > ( ) ) ;
propertyMap . put ( " abc " , modelProperty ) ;
ModelProperty modelProperty1 = new ModelProperty ( " bcd " , stringResolvedType , " java.lang.String " , 0 , true , false , false , false , " 姓名 " , null , null , null , null , null , new ArrayList < > ( ) ) ;
propertyMap . put ( " bcd " , modelProperty1 ) ;
operation . setResponses ( responses ) ;
operations . put ( openApi . getRequestMethod ( ) . toLowerCase ( ) , operation ) ;
paths . put ( " /openapi/call/ " + openApi . getRequestUrl ( ) , operations ) ;
}
ResolvedType mapResolvedType = typeResolver . resolve ( HashMap . clas s) ;
swaggerModel . setDefinitions ( definition s) ;
swaggerModel . setPaths ( paths ) ;
List < ModelReference > subTypes = new ArrayList < > ( ) ;
subTypes . add ( stringModelRef ) ;
}
Model bodyModel = new Model ( " path_body " , " bodyModel " , mapResolvedType , " java.util.HashMap " , pr opertyMap , " 请求体结构 " , " " , " " , subTypes , null , null ) ;
ModelRef bodyRef = new ModelRef ( " bodyModel " , " path_body " , null , null , true , " path_body " ) ;
private void parameters ( SwaggerOperation operation , OpenApi openApi ) {
List < SwaggerOperationParameter > parameters = new ArrayList < > ( ) ;
Set < ResponseMessage > responseMessages = documentation . getApiListings ( ) . get ( " login-controller " ) . get ( 0 ) . getApis ( ) . get ( 2 ) . getOperations ( ) . get ( 0 ) . getResponseMessages ( ) ;
for ( OpenApiParam openApiParam : openApiParamService . findByApiId ( openApi . getId ( ) ) ) {
SwaggerOperationParameter parameter = new SwaggerOperationParameter ( ) ;
parameter . setIn ( " path " ) ;
parameter . setName ( openApiParam . getParamKey ( ) ) ;
parameter . setRequired ( openApiParam . getRequired ( ) = = 1 ) ;
parameter . setDescription ( openApiParam . getNote ( ) ) ;
parameters . add ( parameter ) ;
}
List < Parameter > paramet ers = new ArrayList < > ( ) ;
// header-->请求参数的获取:@RequestHeader()
// query-->请求参数的获取:@RequestParam()
// path-->请求参数的获取:@PathVariable()
// body-->请求参数的获取:@RequestBody()
// form( 不常用)
P arameter body = new P arameter( " bodyModel " ,
" 请求体 " ,
" " ,
true ,
false ,
true ,
bodyRef ,
Optional . of ( mapResolvedType ) ,
null ,
" body " ,
null ,
false ,
null ,
null ,
2147483647 ,
null ,
new HashMap < > ( ) ,
new ArrayList < > ( ) ) ;
for ( OpenApiHeader openApiHead er : openApiHeaderService . findByApiId ( openApi . getId ( ) ) ) {
SwaggerOperationParameter parameter = new SwaggerOperationParameter ( ) ;
parameter . setIn ( " header " ) ;
parameter . setName ( openApiHeader . getHeaderKey ( ) ) ;
parameter . setRequired ( openApiHeader . getRequired ( ) = = 1 ) ;
parameter . setDescription ( openApiHeader . getNote ( ) ) ;
p arameters . add ( p arameter) ;
}
parameters . add ( body ) ;
operation . setParameters ( parameters ) ;
}
Parame ter parameter = new Parameter ( " name " ,
" 姓名 " ,
" 张三 " ,
false ,
false ,
true ,
stringModelRef ,
Optional . empty ( ) ,
null ,
" query " ,
null ,
false ,
null ,
null ,
2147483647 ,
null ,
new HashMap < > ( ) ,
new ArrayList < > ( ) ) ;
priva te SwaggerInfo swaggerInfo ( ) {
SwaggerInfo info = new SwaggerInfo ( ) ;
parameters . add ( parameter ) ;
info . setDescription ( " OpenAPI 接口列表 " ) ;
info . setVersion ( " 3.7.1 " ) ;
info . setTitle ( " OpenAPI 接口列表 " ) ;
info . setTermsOfService ( " https://jeecg.com " ) ;
ModelRef modelRef = new ModelRef ( resultModel . getType ( ) . getTypeName ( ) ,
resultModel . g etQualifiedType ( ) ,
null ,
null ,
false ,
resultModel . getId ( ) ) ;
SwaggerInfoContact contact = new SwaggerInfoContact ( ) ;
contact . s etName ( " jeecg@qq.com " ) ;
Operation operation = new Operation ( HttpMethod . resolve ( " GET " ) ,
" 模拟第一个openapi接口 " ,
" 模拟第一个openapi接口 " ,
modelRef ,
" abcUsingGET " ,
0 , tags , produces , consumes ,
new LinkedHashSet < > ( ) ,
new ArrayList < > ( ) ,
parameters ,
responseMessages ,
" false " ,
false ,
new ArrayList < > ( ) ) ;
info . setContact ( contact ) ;
List < Operation > operatio ns = new ArrayList < > ( ) ;
operatio ns. add ( operation ) ;
SwaggerInfoLicense lice nse = new SwaggerInfoLicense ( ) ;
lice nse . setName ( " Apache 2.0 " ) ;
license . setUrl ( " http://www.apache.org/licenses/LICENSE-2.0.html " ) ;
ApiDescription apiDescription = new ApiDescription ( " openapi " ,
" /jeecg-boot/openapi/call/abc " , " openapi " , operations , false ) ;
info . setLicense ( license ) ;
List < ApiDescription > apiList = new ArrayList < > ( ) ;
apiList . add ( apiDescription ) ;
Map < String , Model > responseModel = new HashMap < > ( ) ;
responseModel . put ( " 接口返回对象«JSONObject» " , resultModel ) ;
responseModel . put ( " bodyModel " , bodyModel ) ;
ApiListing api = new ApiListing ( " 1.0 " ,
" / " ,
" /openapi/call/abc " ,
produces , consumes ,
" " , new HashSet < > ( ) , new ArrayList < > ( ) , apiList , responseModel , " abc " , 0 , apiTags ) ;
apis . add ( api ) ;
documentation . getApiListings ( ) . put ( " openapi " , apis ) ;
return info ;
}
/**
@@ -347,135 +389,4 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
r . setResult ( PathGenerator . genPath ( ) ) ;
return r ;
}
/**
* resetOpenapiSwagger
*/
@Override
public void run ( String . . . args ) throws Exception {
List < OpenApi > openapis = service . list ( ) ;
Documentation documentation = documentationCache . documentationByGroup ( " default " ) ;
List < ApiListing > apis = new ArrayList < > ( ) ;
// --------------------- swagger common --------------
// http参数
Set < String > produces = new HashSet < > ( ) ;
produces . add ( " application/json " ) ;
Set < String > consumes = new HashSet < > ( ) ;
consumes . add ( " application/json " ) ;
// 标题栏
Set < String > tags = new HashSet < > ( ) ;
Tag tag = new Tag ( " openapi " , " openapi " ) ;
tags . add ( " openapi " ) ;
Set < Tag > apiTags = new HashSet < > ( ) ;
apiTags . add ( tag ) ;
documentation . getTags ( ) . add ( tag ) ;
ModelRef stringModelRef = new ModelRef ( " string " , null , false ) ;
// 响应文档
Model resultModel = documentation . getApiListings ( ) . get ( " login-controller " ) . get ( 0 ) . getModels ( ) . get ( " 接口返回对象«JSONObject» " ) ;
Set < ResponseMessage > responseMessages = documentation . getApiListings ( ) . get ( " login-controller " ) . get ( 0 ) . getApis ( ) . get ( 2 ) . getOperations ( ) . get ( 0 ) . getResponseMessages ( ) ;
ModelRef modelRef = new ModelRef ( resultModel . getType ( ) . getTypeName ( ) ,
resultModel . getQualifiedType ( ) ,
null ,
null ,
false ,
resultModel . getId ( ) ) ;
// --------------------- swagger common --------------
for ( OpenApi openapi : openapis ) {
openapi . setParams ( openApiParamService . findByApiId ( openapi . getId ( ) ) ) ;
openapi . setHeaders ( openApiHeaderService . findByApiId ( openapi . getId ( ) ) ) ;
// 参数, 包含header\query\path\body\form 五类数据
List < Parameter > parameters = new ArrayList < > ( ) ;
// header-->请求参数的获取:@RequestHeader()
// query-->请求参数的获取:@RequestParam()
// path-->请求参数的获取:@PathVariable()
// body-->请求参数的获取:@RequestBody()
// form( 不常用)
for ( OpenApiHeader openApiHeader : openapi . getHeaders ( ) ) {
Parameter parameter = new Parameter ( openApiHeader . getHeaderKey ( ) ,
openApiHeader . getNote ( ) ,
openApiHeader . getDefaultValue ( ) ,
openApiHeader . getRequired ( ) = = 1 ,
false ,
true ,
stringModelRef ,
Optional . empty ( ) ,
null ,
" header " ,
null ,
false ,
null ,
null ,
2147483647 ,
null ,
new HashMap < > ( ) ,
new ArrayList < > ( ) ) ;
parameters . add ( parameter ) ;
}
for ( OpenApiParam openApiParam : openapi . getParams ( ) ) {
Parameter parameter = new Parameter ( openApiParam . getParamKey ( ) ,
openApiParam . getNote ( ) ,
openApiParam . getDefaultValue ( ) ,
openApiParam . getRequired ( ) = = 1 ,
false ,
true ,
stringModelRef ,
Optional . empty ( ) ,
null ,
" query " ,
null ,
false ,
null ,
null ,
2147483647 ,
null ,
new HashMap < > ( ) ,
new ArrayList < > ( ) ) ;
parameters . add ( parameter ) ;
}
Operation operation = new Operation ( HttpMethod . resolve ( openapi . getRequestMethod ( ) ) ,
openapi . getName ( ) ,
openapi . getName ( ) ,
modelRef ,
openapi . getName ( ) + " Using " + openapi . getRequestMethod ( ) ,
0 , tags , produces , consumes ,
new LinkedHashSet < > ( ) ,
new ArrayList < > ( ) ,
parameters ,
responseMessages ,
" false " ,
false ,
new ArrayList < > ( ) ) ;
List < Operation > operations = new ArrayList < > ( ) ;
operations . add ( operation ) ;
ApiDescription apiDescription = new ApiDescription ( " openapi " ,
" /jeecg-boot/openapi/call/ " + openapi . getRequestUrl ( ) , openapi . getName ( ) , operations , false ) ;
List < ApiDescription > apiList = new ArrayList < > ( ) ;
apiList . add ( apiDescription ) ;
Map < String , Model > responseModel = new HashMap < > ( ) ;
responseModel . put ( " 接口返回对象«JSONObject» " , resultModel ) ;
ApiListing api = new ApiListing ( " 1.0 " ,
" / " ,
" /openapi/call/ " + openapi . getRequestUrl ( ) ,
produces , consumes ,
" " , new HashSet < > ( ) , new ArrayList < > ( ) , apiList , responseModel , " abc " , 0 , apiTags ) ;
apis . add ( api ) ;
}
documentation . getApiListings ( ) . put ( " openapi " , apis ) ;
}
}