|
|
|
@ -1,251 +0,0 @@
|
|
|
|
|
package com.dsideal.FengHuang.Swagger.controller;
|
|
|
|
|
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.annotation.Api;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.annotation.Item;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.annotation.ActionApi;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.annotation.Param;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.annotation.Params;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.annotation.Responses;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.annotation.SecurityApi;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.config.SwaggerConfig;
|
|
|
|
|
import com.dsideal.FengHuang.Swagger.enums.InType;
|
|
|
|
|
|
|
|
|
|
import com.jfinal.core.Action;
|
|
|
|
|
import com.jfinal.core.Controller;
|
|
|
|
|
import com.jfinal.core.JFinal;
|
|
|
|
|
import com.jfinal.kit.Kv;
|
|
|
|
|
import com.jfinal.kit.Okv;
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
import static java.util.Comparator.*;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Swagger UI Controller
|
|
|
|
|
*/
|
|
|
|
|
public class SwaggerController extends Controller {
|
|
|
|
|
|
|
|
|
|
// 请求方法
|
|
|
|
|
private static final String HTTP_METHOD = "get,post,head,put,delete";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* api页面
|
|
|
|
|
*/
|
|
|
|
|
//@IsLoginInterface({})
|
|
|
|
|
public void index() {
|
|
|
|
|
String theme = getPara(0);
|
|
|
|
|
if (theme == null) {
|
|
|
|
|
theme = "layui";
|
|
|
|
|
} else {
|
|
|
|
|
theme = theme.trim();
|
|
|
|
|
}
|
|
|
|
|
switch (theme) {
|
|
|
|
|
case "default":
|
|
|
|
|
render("_default/index.html");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
render("layui/index.html");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取所有api接口
|
|
|
|
|
*/
|
|
|
|
|
public void api() {
|
|
|
|
|
// 所有接口类tag描述信息
|
|
|
|
|
List<Kv> tags = new ArrayList<>();
|
|
|
|
|
// 所有接口路径
|
|
|
|
|
Map<String, Map<String, Kv>> paths = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
|
|
// 扫描所有API类Action注解
|
|
|
|
|
Map<Class<? extends Controller>, List<Action>> classMap = scanAllApiAction();
|
|
|
|
|
classMap.keySet().forEach(clazz -> {
|
|
|
|
|
List<Action> actions = classMap.get(clazz);
|
|
|
|
|
actions.forEach(action -> {
|
|
|
|
|
Method method = action.getMethod();
|
|
|
|
|
ActionApi ApiAction = method.getAnnotation(ActionApi.class);
|
|
|
|
|
String httpMethod = ApiAction.httpMethod();
|
|
|
|
|
if (httpMethod == null || "".equals(httpMethod.trim())) {
|
|
|
|
|
// 请求方法:HEAD:请求页面的首部、GET:查看, POST:创建, PUT:更新, DELETE:删除
|
|
|
|
|
httpMethod = HTTP_METHOD;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, Kv> methodApiMap = new HashMap<>();
|
|
|
|
|
String[] httpMethods = httpMethod.split(",");// 支持多个请求方法
|
|
|
|
|
for (String methodItem : httpMethods) {
|
|
|
|
|
methodItem = methodItem.trim().toLowerCase();
|
|
|
|
|
if (!Arrays.asList(HTTP_METHOD.split(",")).contains(methodItem)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// 获取参数注解信息
|
|
|
|
|
List<Param> params = new ArrayList<>();
|
|
|
|
|
if (method.isAnnotationPresent(Params.class)) {
|
|
|
|
|
params.addAll(Arrays.asList(method.getAnnotation(Params.class).value()));
|
|
|
|
|
}
|
|
|
|
|
if (method.isAnnotationPresent(Param.class)) {
|
|
|
|
|
// Java8新特性:支持多注解
|
|
|
|
|
Param[] paramArray = method.getAnnotationsByType(Param.class);
|
|
|
|
|
params.addAll(Arrays.asList(paramArray));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建参数列表(包含全局参数)
|
|
|
|
|
List<Kv> paramList = new ArrayList<>(SwaggerConfig.getGlobalParamList());
|
|
|
|
|
params.forEach(i -> {
|
|
|
|
|
// 注意:swaggerUI 使用Java的关键字default作为默认值,此处将defaultValue转换为default
|
|
|
|
|
Kv kv = Kv.by("name", i.name()).set("description", i.remark()).set("required", i.required())
|
|
|
|
|
.set("type", i.dataType()).set("format", i.format()).set("default", i.defaultValue());
|
|
|
|
|
if ("file".equals(i.dataType())) {
|
|
|
|
|
kv.set("in", InType.FORM_DATA.getValue());
|
|
|
|
|
} else {
|
|
|
|
|
kv.set("in", i.in().getValue());
|
|
|
|
|
}
|
|
|
|
|
kv.set("schema", i.schema());//
|
|
|
|
|
kv.set("items", "");//{type:"string",enum:["a","b","c"],default:""}
|
|
|
|
|
kv.set("collectionFormat", i.collectionFormat());
|
|
|
|
|
paramList.add(kv);
|
|
|
|
|
});
|
|
|
|
|
// 每个action注解信息
|
|
|
|
|
Kv actionKv = Kv.by("parameters", paramList)
|
|
|
|
|
.set("operationId", method.getName())
|
|
|
|
|
.set("tags", toSet(notBlank(ApiAction.tag()) ? ApiAction.tag() : actions.get(0).getActionKey()))
|
|
|
|
|
.set("description", ApiAction.remark())
|
|
|
|
|
.set("summary", ApiAction.summary())
|
|
|
|
|
.set("consumes", toSet("application/json" + "," + ApiAction.consumes()))
|
|
|
|
|
.set("produces", toSet(ApiAction.consumes() + "," + "application/json"));
|
|
|
|
|
|
|
|
|
|
// response
|
|
|
|
|
Kv responseKv = Kv.by("200", Kv.by("description", "Success"))
|
|
|
|
|
.set("400", Kv.by("description", "Invalid ID supplied"))
|
|
|
|
|
.set("403", Kv.by("description", "Forbiden"))
|
|
|
|
|
.set("404", Kv.by("description", "Not found"))
|
|
|
|
|
.set("405", Kv.by("description", "Validation exception"))
|
|
|
|
|
.set("500", Kv.by("description", "Interneral error"));
|
|
|
|
|
if (method.isAnnotationPresent(Responses.class)) {
|
|
|
|
|
Responses response = method.getAnnotation(Responses.class);
|
|
|
|
|
responseKv.set(response.key(), Kv.by("description", response.remark()));
|
|
|
|
|
Kv itemKv = Kv.create();
|
|
|
|
|
for (Item i : response.schemaItems()) {
|
|
|
|
|
itemKv.set(i.key(), i.value());
|
|
|
|
|
}
|
|
|
|
|
responseKv.set("schema", Kv.by("type", response.schemaType()).set("items", itemKv));
|
|
|
|
|
actionKv.set("responses", responseKv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// security
|
|
|
|
|
if (method.isAnnotationPresent(SecurityApi.class)) {
|
|
|
|
|
// Java8新特性:支持多注解
|
|
|
|
|
SecurityApi[] securityApis = method.getAnnotationsByType(SecurityApi.class);
|
|
|
|
|
List<Kv> securitys = new ArrayList<>();
|
|
|
|
|
for (SecurityApi item : securityApis) {
|
|
|
|
|
Kv security = Kv.by(item.key(), toSet(item.value()));
|
|
|
|
|
securitys.add(security);
|
|
|
|
|
}
|
|
|
|
|
actionKv.set("security", securitys);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
methodApiMap.put(methodItem, actionKv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
paths.put(notBlank(ApiAction.url()) ? ApiAction.url() : action.getActionKey(), methodApiMap);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Api api = clazz.getAnnotation(Api.class);
|
|
|
|
|
Kv tag = Kv.by("name", actions.get(0).getActionKey()).set("description", api.remark() + " (" + clazz.getSimpleName() + ")");
|
|
|
|
|
//Kv tag = Kv.by("name", api.remark()).set("description", api.remark() + " (" + clazz.getSimpleName() + ")");
|
|
|
|
|
if (notBlank(api.outerUrl()) || notBlank(api.outerRemark())) {
|
|
|
|
|
tag.set("externalDocs", Kv.by("description", api.outerRemark()).set("url", api.outerUrl()));
|
|
|
|
|
}
|
|
|
|
|
tags.add(tag);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 获取host
|
|
|
|
|
String host = getRequest().getServerName();
|
|
|
|
|
if (this.getRequest().getServerPort() != 80) {
|
|
|
|
|
host += ":" + getRequest().getServerPort();
|
|
|
|
|
}
|
|
|
|
|
Okv allApi = Okv.by("Swagger", "2.0")
|
|
|
|
|
.set("info", SwaggerConfig.getApiInfo())
|
|
|
|
|
.set("host", host)
|
|
|
|
|
.set("basePath", "")
|
|
|
|
|
.set("tags", tags)
|
|
|
|
|
.set("schemes", SwaggerConfig.getScheme())// 传输协议Scheme:HTTP、HTTPS
|
|
|
|
|
.set("paths", paths)
|
|
|
|
|
.set("securityDefinitions", SwaggerConfig.getSecurityDefinition())
|
|
|
|
|
.set("definitions", SwaggerConfig.getDefinition())
|
|
|
|
|
.set("externalDocs", SwaggerConfig.getExternalDocs());
|
|
|
|
|
renderJson(allApi);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 扫描所有API类Action注解
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private static Map<Class<? extends Controller>, List<Action>> scanAllApiAction() {
|
|
|
|
|
Map<Class<? extends Controller>, List<Action>> apiMap = new HashMap<>();
|
|
|
|
|
// 获取遍历所有action
|
|
|
|
|
JFinal.me().getAllActionKeys().forEach(actionKey -> {
|
|
|
|
|
Action action = JFinal.me().getAction(actionKey, new String[1]);
|
|
|
|
|
Class<? extends Controller> controller = action.getControllerClass();
|
|
|
|
|
|
|
|
|
|
if (apiMap.containsKey(controller)) {
|
|
|
|
|
if (action.getMethod().isAnnotationPresent(ActionApi.class)) {
|
|
|
|
|
List<Action> actions = apiMap.get(controller);
|
|
|
|
|
if (!actions.contains(action)) {
|
|
|
|
|
actions.add(action);
|
|
|
|
|
apiMap.put(controller, actions);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (controller.isAnnotationPresent(Api.class)) {
|
|
|
|
|
if (action.getMethod().isAnnotationPresent(ActionApi.class)) {
|
|
|
|
|
List<Action> actions = new ArrayList<>();
|
|
|
|
|
actions.add(action);
|
|
|
|
|
apiMap.put(controller, actions);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
List<Class<? extends Controller>> list = new ArrayList<>(apiMap.keySet());
|
|
|
|
|
list.sort(comparingInt((Class<? extends Controller> clazz) -> clazz.getAnnotation(Api.class).sort()));
|
|
|
|
|
|
|
|
|
|
Map<Class<? extends Controller>, List<Action>> result = new LinkedHashMap<>();
|
|
|
|
|
for (Class<? extends Controller> i : list) {
|
|
|
|
|
List<Action> actions = apiMap.get(i);
|
|
|
|
|
actions.sort(comparingInt((Action action) -> action.getMethod().getAnnotation(ActionApi.class).sort()));
|
|
|
|
|
result.put(i, actions);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 字符串转set集合
|
|
|
|
|
*
|
|
|
|
|
* @param value
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private static Set<String> toSet(String value) {
|
|
|
|
|
Set<String> result = new LinkedHashSet<>();
|
|
|
|
|
if (value != null) {
|
|
|
|
|
String[] values = value.split(",");
|
|
|
|
|
for (String item : values) {
|
|
|
|
|
if (notBlank(item)) {
|
|
|
|
|
result.add(item.trim());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 判断字符串非空
|
|
|
|
|
*
|
|
|
|
|
* @param value
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private static boolean notBlank(String value) {
|
|
|
|
|
return value != null && !"".equals(value.trim());
|
|
|
|
|
}
|
|
|
|
|
}
|