Swagger使用方法详解(WebApi)——看完不会用你打我

WebApi接口开发完毕后,交付给前端人员或手机端开发者时接口说明文档是必不可少的配套设备,如果公司流程不规范大家使用口口相传的交接方式,而且没有改进的欲望,那你可以到此为止了。Swagger是方便测试接口,快速展示注释内容,生成Restful风格接口文档的框架。

Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因:

  • Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API。
  • Swagger 可以生成客户端SDK代码用于各种不同的平台上的实现。
  • Swagger 文件可以在许多不同的平台上从代码注释中自动生成。
  • Swagger 有一个强大的社区,里面有许多强悍的贡献者。

按照下述步骤操作,你就能在WebApi中使用Swagger,本文做测试用的版本v5.6.0,好好看吧,如果有可改进的地方,欢迎大家留言。

1、安装Swagger



2、初次运行


3、添加自定义ApiController

public class PleasureController : ApiController
{
    /// <summary>
    /// 获取完整的用户信息
    /// </summary>
    /// <param name="age">年龄</param>
    /// <param name="name">姓名</param>
    /// <returns>完整的用户信息</returns>
    public string GetMessage(int age,string name)
    {
        return string.Format("age={0},name={1}", age, name);
    }
}

4、添加实现了ISwaggerProvider接口的类

在App_Start文件夹中添加SwaggerControllerDescProvider.cs,相关代码如下:

namespace WebApiSwagger.Main.App_Start
{
    /// <summary>
    /// 显示swagger控制器的描述
    /// </summary>
    public class SwaggerControllerDescProvider : ISwaggerProvider
    {
        private readonly ISwaggerProvider _swaggerProvider;
        private static ConcurrentDictionary<string, SwaggerDocument> _cache = new ConcurrentDictionary<string, SwaggerDocument>();
        private readonly string _xml;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="swaggerProvider"></param>
        /// <param name="xml">xml文档路径</param>
        public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
        {
            _swaggerProvider = swaggerProvider;
            _xml = xml;
        }

        public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
        {

            var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
            SwaggerDocument srcDoc = null;
            //只读取一次
            if (!_cache.TryGetValue(cacheKey, out srcDoc))
            {
                srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);

                srcDoc.vendorExtensions = new Dictionary<string, object> { { "ControllerDesc", GetControllerDesc() } };
                _cache.TryAdd(cacheKey, srcDoc);
            }
            return srcDoc;
        }

        /// <summary>
        /// 从API文档中读取控制器描述
        /// </summary>
        /// <returns>所有控制器描述</returns>
        public ConcurrentDictionary<string, string> GetControllerDesc()
        {
            string xmlpath = _xml;
            ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
            if (File.Exists(xmlpath))
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(xmlpath);
                string type = string.Empty, path = string.Empty, controllerName = string.Empty;

                string[] arrPath;
                int length = -1, cCount = "Controller".Length;
                XmlNode summaryNode = null;
                foreach (XmlNode node in xmldoc.SelectNodes("//member"))
                {
                    type = node.Attributes["name"].Value;
                    if (type.StartsWith("T:"))
                    {
                        //控制器
                        arrPath = type.Split('.');
                        length = arrPath.Length;
                        controllerName = arrPath[length - 1];
                        if (controllerName.EndsWith("Controller"))
                        {
                            //获取控制器注释
                            summaryNode = node.SelectSingleNode("summary");
                            string key = controllerName.Remove(controllerName.Length - cCount, cCount);
                            if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
                            {
                                controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
                            }
                        }
                    }
                }
            }
            return controllerDescDict;
        }
    }
}

5、添加功能性js文件

在Scripts文件夹中添加SwaggerConfig.js脚本文件,将其设置为“嵌入的资源”。这个js文件的功能主要有两个:一个是汉化,另一个是在界面上显示控制器的描述文字。

 

'use strict';
window.SwaggerTranslator = {
    _words: [],

    translate: function () {
        var $this = this;
        $('[data-sw-translate]').each(function () {
            $(this).html($this._tryTranslate($(this).html()));
            $(this).val($this._tryTranslate($(this).val()));
            $(this).attr('title', $this._tryTranslate($(this).attr('title')));
        });
    },

    setControllerSummary: function () {
        $.ajax({
            type: "get",
            async: true,
            url: $("#input_baseUrl").val(),
            dataType: "json",
            success: function (data) {
                var summaryDict = data.ControllerDesc;
                var id, controllerName, strSummary;
                $("#resources_container .resource").each(function (i, item) {
                    id = $(item).attr("id");
                    if (id) {
                        controllerName = id.substring(9);
                        strSummary = summaryDict[controllerName];
                        if (strSummary) {
                            $(item).children(".heading").children(".options").first().prepend('<li class="controller-summary" title="' + strSummary + '">' + strSummary + '</li>');
                        }
                    }
                });
            }
        });
    },
    _tryTranslate: function (word) {
        return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
    },

    learn: function (wordsMap) {
        this._words = wordsMap;
    }
};


/* jshint quotmark: double */
window.SwaggerTranslator.learn({
    "Warning: Deprecated": "警告:已过时",
    "Implementation Notes": "实现备注",
    "Response Class": "响应类",
    "Status": "状态",
    "Parameters": "参数",
    "Parameter": "参数",
    "Value": "值",
    "Description": "描述",
    "Parameter Type": "参数类型",
    "Data Type": "数据类型",
    "Response Messages": "响应消息",
    "HTTP Status Code": "HTTP状态码",
    "Reason": "原因",
    "Response Model": "响应模型",
    "Request URL": "请求URL",
    "Response Body": "响应体",
    "Response Code": "响应码",
    "Response Headers": "响应头",
    "Hide Response": "隐藏响应",
    "Headers": "头",
    "Try it out!": "试一下!",
    "Show/Hide": "显示/隐藏",
    "List Operations": "显示操作",
    "Expand Operations": "展开操作",
    "Raw": "原始",
    "can't parse JSON.  Raw result": "无法解析JSON. 原始结果",
    "Model Schema": "模型架构",
    "Model": "模型",
    "apply": "应用",
    "Username": "用户名",
    "Password": "密码",
    "Terms of service": "服务条款",
    "Created by": "创建者",
    "See more at": "查看更多:",
    "Contact the developer": "联系开发者",
    "api version": "api版本",
    "Response Content Type": "响应Content Type",
    "fetching resource": "正在获取资源",
    "fetching resource list": "正在获取资源列表",
    "Explore": "浏览",
    "Show Swagger Petstore Example Apis": "显示 Swagger Petstore 示例 Apis",
    "Can't read from server.  It may not have the appropriate access-control-origin settings.": "无法从服务器读取。可能没有正确设置access-control-origin。",
    "Please specify the protocol for": "请指定协议:",
    "Can't read swagger JSON from": "无法读取swagger JSON于",
    "Finished Loading Resource Information. Rendering Swagger UI": "已加载资源信息。正在渲染Swagger UI",
    "Unable to read api": "无法读取api",
    "from path": "从路径",
    "server returned": "服务器返回"
});
$(function () {
    window.SwaggerTranslator.translate();
    window.SwaggerTranslator.setControllerSummary();
});

6、修改SwaggerConfig.cs

Swagger安装完毕后App_Start文件夹下才会有SwaggerConfig.cs文件,修改后的SwaggerConfig.cs的代码如下:

public class SwaggerConfig
{
    public static void Register()
    {
        var thisAssembly = typeof(SwaggerConfig).Assembly;

        GlobalConfiguration.Configuration
            .EnableSwagger(c =>
                {
                    c.SingleApiVersion("v1", "WebApiSwagger.Main");
                    //添加下述代码                        
                    var xmlFile = string.Format("{0}/bin/WebApiSwagger.Main.XML", System.AppDomain.CurrentDomain.BaseDirectory);
                    if (System.IO.File.Exists(xmlFile))
                    {
                        c.IncludeXmlComments(xmlFile);
                    }
                    c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
                    c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, xmlFile));
                })
            .EnableSwaggerUi(b => 
                {
                    b.InjectJavaScript(Assembly.GetExecutingAssembly(), "WebApiSwagger.Main.Scripts.SwaggerConfig.js");
                });
    }
}

7、修改项目的“XML文档文件”属性

8、注释显示成功

9、小瑕疵及解决方法


如果看官觉得本文对您有些帮助,请点个赞、评论下鼓励鼓励,谢谢。

为了方便大家分享工作心得、交流技术问题,我创建了QQ群389591879,
大家也可以在里边相互了解各自公司的信息,希望能对大家有所帮助,同道中人欢迎加群。

<think>好的,我需要帮助用户了解如何在Swagger-Bootstrap-UI 1.9.3版本中实现类似knife4j的功能配置。首先,我得回忆一下这两个项目的区别和联系。根据用户提供的引用内容,knife4j是Swagger-Bootstrap-UI的升级版,集中了所有特性到knife4j-spring-ui包中,并且提供更多增强功能,比如动态参数、接口排序等。而用户提到的Swagger-Bootstrap-UI 1.9.3是一个较旧的版本,可能缺少knife4j的一些新特性。 接下来,用户想知道如何在1.9.3版本中配置出类似knife4j的功能。我需要检查旧版本是否支持这些功能,或者是否有替代方法。根据引用3,knife4j的增强功能需要添加@EnableKnife4j注解,而旧版本可能没有这个。可能需要手动配置或调整代码。 首先,界面美化方面,Swagger-Bootstrap-UI 1.9.3已经有自己的UI改进,可能接近knife4j的界面,但需要确认是否支持主题切换或自定义CSS。引用3提到knife4j解决了界面丑的问题,所以旧版本可能界面不够美观,但用户可能需要手动调整。 其次,功能增强如动态参数、参数过滤、接口排序。旧版本可能不支持这些,但可以通过其他方式实现。例如,接口分组可以使用Swagger的@Group注解,或者配置Docket实例来分组。参数过滤可能需要自定义注解或过滤器,处理请求参数。接口排序可能需要手动在代码中调整接口定义的顺序,或者使用Swagger的@Api注解的position属性。 另外,离线文档导出功能,旧版本可能支持通过前端导出,或者需要依赖其他库。引用1提到Swagger-Bootstrap-UI的纯前端版本可以导出,所以用户可能需要集成前端资源来实现。 还需要考虑依赖管理,用户可能需要添加或升级相关的Maven/Gradle依赖,确保没有冲突。例如,检查是否引入了正确的springfox-swaggerSwagger-Bootstrap-UI版本。 最后,可能存在的局限性,比如旧版本无法完全实现knife4j的所有功能,这时需要建议用户考虑升级到knife4j以获得更好的支持。同时,提供替代方案和配置步骤,帮助用户尽可能接近所需功能。 总结步骤:界面优化配置、功能增强实现、文档导出、依赖管理,最后指出局限性并建议升级。需要确保每个步骤具体可行,并参考用户提供的引用内容,特别是引用3中的注解说明和访问方式。</think>### Swagger-Bootstrap-UI 1.9.3 实现类似knife4j的配置方法 #### 1. 界面优化配置 Swagger-Bootstrap-UI 1.9.3 默认界面已优于原生Swagger,但需通过以下配置接近knife4j的增强效果: ```xml <!-- 添加Maven依赖 --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.3</version> </dependency> ``` 在Spring Boot启动类中添加注解: ```java @EnableSwagger2 @EnableSwaggerBootstrapUI // 启用增强UI public class Application { ... } ``` 访问地址为:$http://host:port/doc.html$[^3] #### 2. 功能增强实现 | 功能 | 实现方法 | |---------------|-----------------------------------------------------------------------------------------| | 接口排序 | 在Controller类添加$@Api(tags = "模块名称")$,同类接口自动分组并按字母排序 | | 参数过滤 | 使用$@ApiImplicitParams$定义动态参数,或通过$Docket.ignoredParameterTypes()$全局过滤 | | 文档调试 | 启用`EnableSwaggerBootstrapUI`后,默认支持Header参数动态修改和全局参数配置 | #### 3. 离线文档导出 通过前端页面导出Markdown/HTML: 1. 访问$http://host:port/doc.html$ 2. 点击**文档管理** -> **离线文档** 3. 选择格式导出(需确保已引入前端资源)[^1] #### 4. 高级配置示例 ```java @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .securitySchemes(Collections.singletonList(new ApiKey("token", "token", "header"))) .select() .apis(RequestHandlerSelectors.basePackage("com.example")) .paths(PathSelectors.any()) .build() .ignoredParameterTypes(HttpServletRequest.class); // 过滤特定参数 } ``` #### 5. 功能对比与局限 | 特性 | Swagger-Bootstrap-UI 1.9.3 | knife4j | |--------------------|----------------------------|--------------------| | 接口排序 | 基础分组排序 | 支持自定义排序规则 | | 动态参数调试 | 手动添加Header | 可视化参数管理 | | 文档权限控制 | 需自行整合安全框架 | 内置登录鉴权 | **建议**:如需完整的增强功能(如接口排序算法、OAuth2集成),推荐迁移至knife4j,仅需替换依赖为: ```xml <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> ``` 并添加$@EnableKnife4j$注解[^3]
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

若恰好帮到您,请随心打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值