iis 浏览网站鹤壁建设网站推广渠道
iis 浏览网站,鹤壁建设网站推广渠道,一个域名可以建几个网站,wordpress主页显示标题设置目录 一、前言二、登录torna三、创建/选择空间四、创建/选择项目五、创建/选择应用六、获取应用的token七、服务推送7.1 引入maven依赖7.2 test下面按照如下方式新建文件 一、前言
Torna作为一款企业级文档管理系统#xff0c;支持了很多种接口文档的推送方式。官方比较推荐的… 目录 一、前言二、登录torna三、创建/选择空间四、创建/选择项目五、创建/选择应用六、获取应用的token七、服务推送7.1 引入maven依赖7.2 test下面按照如下方式新建文件 一、前言
Torna作为一款企业级文档管理系统支持了很多种接口文档的推送方式。官方比较推荐的一种方式就是使用smart-doc插件推送该插件需要完善接口代码中的javadoc相对来说代码规范性要求较高。 使用方式如下 接口文档管理解决方案调研及TornaSmart-doc的使用
这里由于某些老项目javadoc并不规范而且某些接口连swagger注解都没有。所以在这里提供了一种基于swagger插件的方式利用main方法推送文档至torna的方式。
二、登录torna 三、创建/选择空间
这里空间可以配置为某个具体的环境例如开发环境、测试环境。
四、创建/选择项目 五、创建/选择应用 六、获取应用的token 七、服务推送
说明: 由于默认的swagger插件只支持扫描带有Api的Controller以及只带有ApiOperation的接口方法这里兼容了无swagger注解的接口推送。 7.1 引入maven依赖 dependencygroupIdcn.torna/groupIdartifactIdswagger-plugin/artifactIdversion1.2.14/versionscopetest/scope/dependency7.2 test下面按照如下方式新建文件 torna.json
{// 开启推送enable: true,// 扫描package多个用;隔开basePackage: com.product,// 推送URLIP端口对应Torna服务器url: http://test.xxx.com:7700/torna/api,// 模块token,复制应用的tokentoken: xxxxxxxxxxxxxxxxxxxxxxxxxx,debugEnv: test,https://test.xxx.com/product,// 推送人author: author,// 打开调试:true/falsedebug: true,// 是否替换文档true替换false不替换追加。默认trueisReplace: false
}DocPushTest.java
import cn.torna.swaggerplugin.TmlySwaggerPlugin;public class DocPushTest {public static void main(String[] args) {TmlySwaggerPlugin.pushDoc();}
}TmlySwaggerPlugin.java
package cn.torna.swaggerplugin;import cn.torna.swaggerplugin.bean.TornaConfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StreamUtils;import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;public class TmlySwaggerPlugin {/*** 推送文档前提把codetorna.json/code文件复制到resources下*/public static void pushDoc() {pushDoc(torna.json);}/*** 推送swagger文档** param configFile 配置文件*/public static void pushDoc(String configFile) {pushDoc(configFile, TmlySwaggerPluginService.class);}public static void pushDoc(String configFile, Class? extends SwaggerPluginService swaggerPluginServiceClazz) {ClassPathResource classPathResource new ClassPathResource(configFile);if (!classPathResource.exists()) {throw new IllegalArgumentException(找不到文件: configFile 请确保resources下有torna.json);}System.out.println(加载Torna配置文件: configFile);try {InputStream inputStream classPathResource.getInputStream();String json StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);JSONObject jsonObject JSON.parseObject(json);TornaConfig tornaConfig jsonObject.toJavaObject(TornaConfig.class);Constructor? extends SwaggerPluginService constructor swaggerPluginServiceClazz.getConstructor(TornaConfig.class);SwaggerPluginService swaggerPluginService constructor.newInstance(tornaConfig);swaggerPluginService.pushDoc();} catch (IOException | InstantiationException | IllegalAccessException | NoSuchMethodException |InvocationTargetException e) {e.printStackTrace();throw new RuntimeException(推送文档出错, e);}}
}TmlySwaggerPluginService.java
package cn.torna.swaggerplugin;import cn.torna.sdk.param.DocItem;
import cn.torna.swaggerplugin.bean.Booleans;
import cn.torna.swaggerplugin.bean.ControllerInfo;
import cn.torna.swaggerplugin.bean.PluginConstants;
import cn.torna.swaggerplugin.bean.TornaConfig;
import cn.torna.swaggerplugin.builder.MvcRequestInfoBuilder;
import cn.torna.swaggerplugin.builder.RequestInfoBuilder;
import cn.torna.swaggerplugin.exception.HiddenException;
import cn.torna.swaggerplugin.exception.IgnoreException;
import cn.torna.swaggerplugin.util.ClassUtil;
import cn.torna.swaggerplugin.util.PluginUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.stream.Collectors;public class TmlySwaggerPluginService extends SwaggerPluginService {private final TornaConfig tornaConfig;public TmlySwaggerPluginService(TornaConfig tornaConfig) {super(tornaConfig);this.tornaConfig tornaConfig;}public void pushDoc() {if (!tornaConfig.getEnable()) {return;}String basePackage tornaConfig.getBasePackage();if (StringUtils.isEmpty(basePackage)) {throw new IllegalArgumentException(basePackage can not empty.);}this.doPush();this.pushCode();}protected void doPush() {String packageConfig tornaConfig.getBasePackage();String[] pkgs packageConfig.split(;);SetClass? classes new HashSet();for (String basePackage : pkgs) {
// SetClass? clazzs ClassUtil.getClasses(basePackage, Api.class);// 把带有RestController的控制层抽取出来SetClass? clazzs ClassUtil.getClasses(basePackage, RestController.class);classes.addAll(clazzs);}MapControllerInfo, ListDocItem controllerDocMap new HashMap(32);for (Class? clazz : classes) {ControllerInfo controllerInfo;try {controllerInfo buildControllerInfo(clazz);} catch (HiddenException | IgnoreException e) {System.out.println(e.getMessage());continue;}ListDocItem docItems controllerDocMap.computeIfAbsent(controllerInfo, k - new ArrayList());ReflectionUtils.doWithMethods(clazz, method - {try {DocItem apiInfo this.buildDocItem(new MvcRequestInfoBuilder(method, tornaConfig));docItems.add(apiInfo);} catch (HiddenException | IgnoreException e) {System.out.println(e.getMessage());} catch (Exception e) {System.out.printf(Create doc error, method:%s%n, method);throw new RuntimeException(e.getMessage(), e);}}, this::match);}ListDocItem docItems mergeSameFolder(controllerDocMap);this.push(docItems);}private ControllerInfo buildControllerInfo(Class? controllerClass) throws HiddenException, IgnoreException {Api api AnnotationUtils.findAnnotation(controllerClass, Api.class);ApiIgnore apiIgnore AnnotationUtils.findAnnotation(controllerClass, ApiIgnore.class);if (api ! null api.hidden()) {throw new HiddenException(Hidden docApi.hiddentrue api.value());}if (apiIgnore ! null) {throw new IgnoreException(Ignore docApiIgnore controllerClass.getName());}String name, description;int position 0;if (api null) {name controllerClass.getSimpleName();description ;} else {name api.value();if (StringUtils.isEmpty(name) api.tags().length 0) {name api.tags()[0];}description api.description();position api.position();}ControllerInfo controllerInfo new ControllerInfo();controllerInfo.setName(name);controllerInfo.setDescription(description);controllerInfo.setPosition(position);return controllerInfo;}/*** 合并控制层文档* 按照控制层类的顺序及名称(Api为value,否则类的getSimpleName)合并为一个有序的文档数组** param controllerDocMap 控制层-文档集合* return*/private ListDocItem mergeSameFolder(MapControllerInfo, ListDocItem controllerDocMap) {// key文件夹value文档MapString, ListDocItem folderDocMap new HashMap();controllerDocMap.forEach((key, value) - {ListDocItem docItems folderDocMap.computeIfAbsent(key.getName(), k - new ArrayList());docItems.addAll(value);});ListControllerInfo controllerInfoList controllerDocMap.keySet().stream().sorted(Comparator.comparing(ControllerInfo::getPosition)).collect(Collectors.toList());ListDocItem folders new ArrayList(controllerDocMap.size());for (Map.EntryString, ListDocItem entry : folderDocMap.entrySet()) {String name entry.getKey();ControllerInfo info controllerInfoList.stream().filter(controllerInfo - name.equals(controllerInfo.getName())).findFirst().orElse(null);if (info null) {continue;}DocItem docItem new DocItem();docItem.setName(name);docItem.setDefinition(info.getDescription());docItem.setOrderIndex(info.getPosition());docItem.setIsFolder(Booleans.TRUE);ListDocItem items entry.getValue();items.sort(Comparator.comparing(DocItem::getOrderIndex));docItem.setItems(items);folders.add(docItem);}return folders;}protected DocItem buildDocItem(RequestInfoBuilder requestInfoBuilder) throws HiddenException, IgnoreException {Method method requestInfoBuilder.getMethod();ApiOperation apiOperation method.getAnnotation(ApiOperation.class);ApiIgnore apiIgnore method.getAnnotation(ApiIgnore.class);if (apiOperation ! null apiOperation.hidden()) {throw new HiddenException(Hidden APIApiOperation.hiddentrue apiOperation.value());}if (apiIgnore ! null) {throw new IgnoreException(Ignore APIApiIgnore apiOperation.value());}return this.doBuildDocItem(requestInfoBuilder);}/*** 兼容方法名上ApiOperation为空的情况** param requestInfoBuilder* return*/protected DocItem doBuildDocItem(RequestInfoBuilder requestInfoBuilder) {ApiOperation apiOperation requestInfoBuilder.getApiOperation();Method method requestInfoBuilder.getMethod();DocItem docItem new DocItem();String httpMethod getHttpMethod(requestInfoBuilder);docItem.setAuthor(apiOperation ! null ? buildAuthor(apiOperation) : );docItem.setName(apiOperation ! null ? apiOperation.value() : method.getName());docItem.setDescription(apiOperation ! null ? apiOperation.notes() : );docItem.setOrderIndex(apiOperation ! null ? buildOrder(apiOperation, method) : 0);docItem.setUrl(requestInfoBuilder.buildUrl());String contentType buildContentType(requestInfoBuilder);docItem.setHttpMethod(httpMethod);docItem.setContentType(contentType);docItem.setIsFolder(PluginConstants.FALSE);docItem.setPathParams(buildPathParams(method));docItem.setHeaderParams(buildHeaderParams(method));docItem.setQueryParams(buildQueryParams(method, httpMethod));TmlyDocParamWrapper reqWrapper new TmlyDocParamWrapper();BeanUtils.copyProperties(buildRequestParams(method, httpMethod), reqWrapper);TmlyDocParamWrapper respWrapper new TmlyDocParamWrapper();BeanUtils.copyProperties(buildResponseParams(method), respWrapper);docItem.setRequestParams(reqWrapper.getData());docItem.setResponseParams(respWrapper.getData());docItem.setIsRequestArray(reqWrapper.getIsArray());docItem.setRequestArrayType(reqWrapper.getArrayType());docItem.setIsResponseArray(respWrapper.getIsArray());docItem.setResponseArrayType(respWrapper.getArrayType());docItem.setErrorCodeParams(apiOperation ! null ? buildErrorCodes(apiOperation) : new ArrayList(0));return docItem;}private String getHttpMethod(RequestInfoBuilder requestInfoBuilder) {ApiOperation apiOperation requestInfoBuilder.getApiOperation();Method method requestInfoBuilder.getMethod();if (apiOperation ! null StringUtils.hasText(apiOperation.httpMethod())) {return apiOperation.httpMethod();}RequestMapping requestMapping AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);if (requestMapping ! null) {RequestMethod[] methods requestMapping.method();if (methods.length 0) {return this.tornaConfig.getMethodWhenMulti();} else {return methods[0].name();}}return tornaConfig.getDefaultHttpMethod();}private String buildContentType(RequestInfoBuilder requestInfoBuilder) {ApiOperation apiOperation requestInfoBuilder.getApiOperation();Method method requestInfoBuilder.getMethod();if (apiOperation ! null StringUtils.hasText(apiOperation.consumes())) {return apiOperation.consumes();}String[] consumeArr getConsumes(method);if (consumeArr ! null consumeArr.length 0) {return consumeArr[0];}Parameter[] methodParameters method.getParameters();if (methodParameters.length 0) {return ;}for (Parameter methodParameter : methodParameters) {RequestBody requestBody methodParameter.getAnnotation(RequestBody.class);if (requestBody ! null) {return MediaType.APPLICATION_JSON_VALUE;}if (PluginUtil.isFileParameter(methodParameter)) {return MediaType.MULTIPART_FORM_DATA_VALUE;}}return getTornaConfig().getGlobalContentType();}private String[] getConsumes(Method method) {RequestMapping requestMapping AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);if (requestMapping ! null) {return requestMapping.consumes();}return null;}public boolean match(Method method) {ListString scanApis this.tornaConfig.getScanApis();if (CollectionUtils.isEmpty(scanApis)) {
// return method.getAnnotation(ApiOperation.class) ! null;return AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class);}for (String scanApi : scanApis) {String methodName method.toString();if (methodName.contains(scanApi)) {return true;}}return false;}DataAllArgsConstructorNoArgsConstructorprivate static class TmlyDocParamWrapperT {/*** 是否数组*/private Byte isArray;/*** 数组元素类型*/private String arrayType;private ListT data;}}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/89114.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!