精华内容
下载资源
问答
  • Swagger生成webapi文档

    2020-02-25 18:55:48
    WebApi接口开发完毕后,交付给前端人员或手机端开发者时接口说明文档是必不可少的配套设备,如果公司流程不规范大家使用口口相传的交接方式,而且没有改进的欲望,那你可以到...

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

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

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

    1、安装Swashbuckle

    2、初次运行 输入 自己网站地址/swagger 我这里是http://www.permissionapi.com/swagger

    3、添加自定义ApiController

    
     
    1. public class AdminController : ApiController
    2. {
    3. /// <summary>
    4. /// 获取管理员信息
    5. /// </summary>
    6. /// <param name="username">管理员姓名</param>
    7. /// <param name="pwd">管理员密码</param>
    8. /// <returns></returns>
    9. public string Get(string username,string pwd)
    10. {
    11. return $"username:{username},pwd:{pwd}";
    12. }
    13. }

     

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

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

    
     
    1. namespace WebApiSwagger.Main.App_Start
    2. {
    3. /// <summary>
    4. /// 显示swagger控制器的描述
    5. /// </summary>
    6. public class SwaggerControllerDescProvider : ISwaggerProvider
    7. {
    8. private readonly ISwaggerProvider _swaggerProvider;
    9. private static ConcurrentDictionary< string, SwaggerDocument> _cache = new ConcurrentDictionary< string, SwaggerDocument>();
    10. private readonly string _xml;
    11. /// <summary>
    12. ///
    13. /// </summary>
    14. /// <param name="swaggerProvider"></param>
    15. /// <param name="xml">xml文档路径</param>
    16. public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
    17. {
    18. _swaggerProvider = swaggerProvider;
    19. _xml = xml;
    20. }
    21. public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
    22. {
    23. var cacheKey = string.Format( "{0}_{1}", rootUrl, apiVersion);
    24. SwaggerDocument srcDoc = null;
    25. //只读取一次
    26. if (!_cache.TryGetValue(cacheKey, out srcDoc))
    27. {
    28. srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
    29. srcDoc.vendorExtensions = new Dictionary< string, object> { { "ControllerDesc", GetControllerDesc() } };
    30. _cache.TryAdd(cacheKey, srcDoc);
    31. }
    32. return srcDoc;
    33. }
    34. /// <summary>
    35. /// 从API文档中读取控制器描述
    36. /// </summary>
    37. /// <returns>所有控制器描述</returns>
    38. public ConcurrentDictionary<string, string> GetControllerDesc()
    39. {
    40. string xmlpath = _xml;
    41. ConcurrentDictionary< string, string> controllerDescDict = new ConcurrentDictionary< string, string>();
    42. if (File.Exists(xmlpath))
    43. {
    44. XmlDocument xmldoc = new XmlDocument();
    45. xmldoc.Load(xmlpath);
    46. string type = string.Empty, path = string.Empty, controllerName = string.Empty;
    47. string[] arrPath;
    48. int length = -1, cCount = "Controller".Length;
    49. XmlNode summaryNode = null;
    50. foreach (XmlNode node in xmldoc.SelectNodes( "//member"))
    51. {
    52. type = node.Attributes[ "name"].Value;
    53. if (type.StartsWith( "T:"))
    54. {
    55. //控制器
    56. arrPath = type.Split( '.');
    57. length = arrPath.Length;
    58. controllerName = arrPath[length - 1];
    59. if (controllerName.EndsWith( "Controller"))
    60. {
    61. //获取控制器注释
    62. summaryNode = node.SelectSingleNode( "summary");
    63. string key = controllerName.Remove(controllerName.Length - cCount, cCount);
    64. if (summaryNode != null && ! string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
    65. {
    66. controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
    67. }
    68. }
    69. }
    70. }
    71. }
    72. return controllerDescDict;
    73. }
    74. }
    75. }

    5、添加功能性js文件

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

    代码如下:

    
     
    1. 'use strict';
    2. window.SwaggerTranslator = {
    3. _words: [],
    4. translate: function () {
    5. var $ this = this;
    6. $( '[data-sw-translate]').each( function () {
    7. $( this).html($ this._tryTranslate($( this).html()));
    8. $( this).val($ this._tryTranslate($( this).val()));
    9. $( this).attr( 'title', $ this._tryTranslate($( this).attr( 'title')));
    10. });
    11. },
    12. setControllerSummary: function () {
    13. $.ajax({
    14. type: "get",
    15. async: true,
    16. url: $( "#input_baseUrl").val(),
    17. dataType: "json",
    18. success: function (data) {
    19. var summaryDict = data.ControllerDesc;
    20. var id, controllerName, strSummary;
    21. $( "#resources_container .resource").each( function (i, item) {
    22. id = $(item).attr( "id");
    23. if (id) {
    24. controllerName = id.substring( 9);
    25. strSummary = summaryDict[controllerName];
    26. if (strSummary) {
    27. $(item).children( ".heading").children( ".options").first().prepend( '<li class="controller-summary" title="' + strSummary + '">' + strSummary + '</li>');
    28. }
    29. }
    30. });
    31. }
    32. });
    33. },
    34. _tryTranslate: function (word) {
    35. return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
    36. },
    37. learn: function (wordsMap) {
    38. this._words = wordsMap;
    39. }
    40. };
    41. /* jshint quotmark: double */
    42. window.SwaggerTranslator.learn({
    43. "Warning: Deprecated": "警告:已过时",
    44. "Implementation Notes": "实现备注",
    45. "Response Class": "响应类",
    46. "Status": "状态",
    47. "Parameters": "参数",
    48. "Parameter": "参数",
    49. "Value": "值",
    50. "Description": "描述",
    51. "Parameter Type": "参数类型",
    52. "Data Type": "数据类型",
    53. "Response Messages": "响应消息",
    54. "HTTP Status Code": "HTTP状态码",
    55. "Reason": "原因",
    56. "Response Model": "响应模型",
    57. "Request URL": "请求URL",
    58. "Response Body": "响应体",
    59. "Response Code": "响应码",
    60. "Response Headers": "响应头",
    61. "Hide Response": "隐藏响应",
    62. "Headers": "头",
    63. "Try it out!": "试一下!",
    64. "Show/Hide": "显示/隐藏",
    65. "List Operations": "显示操作",
    66. "Expand Operations": "展开操作",
    67. "Raw": "原始",
    68. "can't parse JSON. Raw result": "无法解析JSON. 原始结果",
    69. "Model Schema": "模型架构",
    70. "Model": "模型",
    71. "apply": "应用",
    72. "Username": "用户名",
    73. "Password": "密码",
    74. "Terms of service": "服务条款",
    75. "Created by": "创建者",
    76. "See more at": "查看更多:",
    77. "Contact the developer": "联系开发者",
    78. "api version": "api版本",
    79. "Response Content Type": "响应Content Type",
    80. "fetching resource": "正在获取资源",
    81. "fetching resource list": "正在获取资源列表",
    82. "Explore": "浏览",
    83. "Show Swagger Petstore Example Apis": "显示 Swagger Petstore 示例 Apis",
    84. "Can't read from server. It may not have the appropriate access-control-origin settings.": "无法从服务器读取。可能没有正确设置access-control-origin。",
    85. "Please specify the protocol for": "请指定协议:",
    86. "Can't read swagger JSON from": "无法读取swagger JSON于",
    87. "Finished Loading Resource Information. Rendering Swagger UI": "已加载资源信息。正在渲染Swagger UI",
    88. "Unable to read api": "无法读取api",
    89. "from path": "从路径",
    90. "server returned": "服务器返回"
    91. });
    92. $( function () {
    93. window.SwaggerTranslator.translate();
    94. window.SwaggerTranslator.setControllerSummary();
    95. });

    6、修改SwaggerConfig.cs

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

    注意代码中 JiaHua.Permission.Api是项目名称,请改成自己项目对应的名称!

    
     
    1. public class SwaggerConfig
    2. {
    3. public static void Register()
    4. {
    5. var thisAssembly = typeof(SwaggerConfig).Assembly;
    6. GlobalConfiguration.Configuration
    7. .EnableSwagger(c =>
    8. {
    9. c.SingleApiVersion( "v1", "JiaHua.Permission.Api");
    10. //添加下述代码
    11. var xmlFile = string.Format( "{0}/bin/JiaHua.Permission.Api.XML", System.AppDomain.CurrentDomain.BaseDirectory);
    12. if (System.IO.File.Exists(xmlFile))
    13. {
    14. c.IncludeXmlComments(xmlFile);
    15. }
    16. c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
    17. c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, xmlFile));
    18. })
    19. .EnableSwaggerUi(b =>
    20. {
    21. b.InjectJavaScript(Assembly.GetExecutingAssembly(), "JiaHua.Permission.Api.Scripts.SwaggerConfig.js");
    22. });
    23. }
    24. }

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

    右键项目--》属性--》生成

    8、注释显示成功

    9、小瑕疵及解决方法

     

    •                     <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                              <use xlink:href="#csdnc-thumbsup"></use>
                          </svg><span class="name">点赞</span>
                          <span class="count"></span>
                          </a></li>
                          <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                              <use xlink:href="#icon-csdnc-Collection-G"></use>
                          </svg><span class="name">收藏</span></a></li>
                          <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                              <use xlink:href="#icon-csdnc-fenxiang"></use>
                          </svg>分享</a></li>
                          <!--打赏开始-->
                                                  <!--打赏结束-->
                                                  <li class="tool-item tool-more">
                              <a>
                              <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                              </a>
                              <ul class="more-box">
                                  <li class="item"><a class="article-report">文章举报</a></li>
                              </ul>
                          </li>
                                              </ul>
                  </div>
                                  <div class="right-toolbox"><a href="https://blog.csdn.net/xiaouncle/article/details/83995809" target="_blank" class="jump-net-article">
                  <svg t="1575545252354" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5597" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M243.9 1022.2c-62.3 0-124-23.8-171.5-70.8C26.4 905.5 1.5 845 1.5 779.9s24.9-125.6 70.8-171.5l184-184.1c45.9-45.9 106.4-70.8 171.5-70.8s125.6 24.9 171.5 70.8c18.1 18.1 18.1 47 0 65.1s-47 18.1-65.1 0c-28.3-28.3-65.7-43.5-105.9-43.5s-78.1 15.3-105.9 43.7l-184 184c-58.3 58.3-58.3 153.4 0 212.3 28.3 28.3 65.7 43.5 105.9 43.5s78.1-15.3 105.9-43.5l184-184c18.1-18.1 47-18.1 65.1 0 18.1 18.1 18.1 47 0 65.1l-184 184c-46.9 48-109.1 71.2-171.4 71.2z m523.7-423l184-184c94.5-94.5 94.5-248 0-342.5s-248-94.5-342.5 0l-184 184c-18.1 18.1-18.1 47 0 65.1s47 18.1 65.1 0l184-184c28.3-28.3 65.7-43.5 105.9-43.5s78.1 15.3 105.9 43.5c58.3 58.3 58.3 153.4 0 212.3l-184 184c-58.3 58.3-153.4 58.3-212.3 0-18.1-18.1-47-18.1-65.1 0-18.1 18.1-18.1 47 0 65.1 47 47 109.3 70.8 171.5 70.8s123.9-23.2 171.5-70.8z" p-id="5598"></path></svg>
                      站内首发文章</a></div>
                              </div>
              <div class="person-messagebox">
                  <div class="left-message"><a href="https://blog.csdn.net/huan13479195089">
                      <img src="https://profile.csdnimg.cn/B/B/D/3_huan13479195089" class="avatar_pic" username="huan13479195089">
                                              <img src="https://g.csdnimg.cn/static/user-reg-year/2x/10.png" class="user-years">
                                      </a></div>
                  <div class="middle-message">
                                          <div class="title"><span class="tit"><a href="https://blog.csdn.net/huan13479195089" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">sufengmarket</a></span>
                                              </div>
                      <div class="text"><span>发布了13 篇原创文章</span> · <span>获赞 1</span> · <span>访问量 4350</span></div>
                  </div>
                                  <div class="right-message">
                                              <a href="https://im.csdn.net/im/main.html?userName=huan13479195089" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                          </a>
                                                              <a class="btn btn-sm attented bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">已关注</a>
                                      </div>
                              </div>
                      </div>
      
    展开全文
  • Swagger框架:使用swagger自动生成API

    千次阅读 2018-07-17 20:51:13
     最近开的项目是巴斯夫公司的BCG项目,项目的后台框架阶段我选择了Swagger框架来实现API的生成。  该项目的后台技术框架有:SpringBoot+Spring Security+JWT+MyBatis+Swagger+POI Swagger介绍:  个人感觉...

    项目情况:

             最近开的项目是巴斯夫公司的BCG项目,项目的后台框架阶段我选择了Swagger框架来实现API的生成。

             该项目的后台技术框架有:SpringBoot+Spring Security+JWT+MyBatis+Swagger+POI

    Swagger介绍:

             个人感觉Swagger相当的方便,通过注解的方式将Controller层的方法自动生成到swagger-ui.html中,在该页面可以看到输入参数的格式、访问路径、返回的响应参数等。与postman类似,但比postman方便一点。而且前后端分离的情况下,后台代码发布到服务器上就可以让前端开发查看到swagger-ui.html。这样每次后台修改过代码之后,代码一发布,前端就可以看到最新的接口信息,省去了写wiki之类的时间。

    项目整合Swagger框架步骤:

        第一步:添加相关依赖:

    <!--swagger框架-->
    <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger2</artifactId>
       <version>2.6.0</version>
    </dependency>
    
    <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger-ui</artifactId>
       <version>2.6.0</version>
    </dependency>

       第二步:建立配置类,添加配置信息(这里我添加的请求头Authorization是由于我使用了jwt框架首先登陆校验,需要swagger能够发送token信息)

    package com.handlecar.basf_bcg_service.conf;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.ParameterBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.schema.ModelRef;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Parameter;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Configuration
    @EnableSwagger2
    public class Swagger2Configuration {
    
        @Bean
        public Docket createRestApi() {
            //添加head参数start
            ParameterBuilder tokenPar = new ParameterBuilder();
            List<Parameter> pars = new ArrayList<Parameter>();
            tokenPar.name("Authorization")
                    .description("令牌")
                    .modelRef(new ModelRef("string"))
                    .parameterType("header")
                    .required(false)
                    .build();
            pars.add(tokenPar.build());
            //添加head参数end
    
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.handlecar.basf_bcg_service"))  // 选择那些路径和api会生成document
                    .paths(PathSelectors.any())  // 对所有路径进行监控
                    .build()
                    .globalOperationParameters(pars);
        }
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("巴斯夫BCG的API")
                    .description("巴斯夫BCG的API")
                    .termsOfServiceUrl("http://localhost:9001")
                    .version("1.0")
                    .build();
        }
    }
    

    注意:@EnableSwagger2注解不可少

     

    第三步:运行项目,在浏览器地址栏输入:http://localhost:8080/swagger-ui.html  (这里的swagger-ui.html是swagger框架运行后自动生成的,不需要自己编写,也不会再项目中出现)

    在这个时候你可能会发现swagger-ui.html不能正常显示,这可能是你的过滤器拦截器拦截了请求。我这里是由于Security安全校验框架导致的。这时候你需要对相应的配置进行修改:

    package com.handlecar.basf_bcg_service.conf;
    
    import com.handlecar.basf_bcg_service.filter.JwtAuthenticationTokenFilter;
    import com.handlecar.basf_bcg_service.security.JwtTokenUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    @Configuration
    //@EnableWebSecurity is used to enable Spring Security’s web security support and provide the Spring MVC integration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    
        // Spring会自动寻找同样类型的具体类注入,这里就是JwtUserDetailsServiceImpl了
        @Autowired
        private UserDetailsService userDetailsService;
    
        @Autowired
        public WebSecurityConfig(UserDetailsService userDetailsService) {
            this.userDetailsService = userDetailsService;
        }
    
    
        //父类WebSecurityConfigurerAdapter有AuthenticationManagerBuilder类成员变量 (private AuthenticationManagerBuilder authenticationBuilder;)
        //以下相当于重载了父类的该成员变量(先自动装配一个实例authenticationManagerBuilder,再进行相关设置,然后被引入作为本类实例的一个成员变量),
        //之后该重载后的成员变量会被框架代码使用到。
        @Autowired
        public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
            authenticationManagerBuilder
                    // 设置UserDetailsService
                    .userDetailsService(this.userDetailsService)
                    // 使用BCrypt进行密码的hash
                    .passwordEncoder(passwordEncoder());
        }
    
        // 装载BCrypt密码编码器
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Bean
        public JwtTokenUtil jwtTokenUtil(){
            return new JwtTokenUtil();
        }
    
        @Bean
        public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
            return new JwtAuthenticationTokenFilter();
        }
    
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    // 由于使用的是JWT,我们这里不需要csrf,不用担心csrf攻击
                    .csrf().disable()
                    // 基于token,所以不需要session
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
    
                    .authorizeRequests()
                        //.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
    
                        // 允许对于网站静态资源的无授权访问
                        .antMatchers(
                            HttpMethod.GET,
                            "/",
                            "/*.html",
                            "/favicon.ico",
                            "/**/*.html",
                            "/**/*.css",
                            "/**/*.js",
                            "/webjars/springfox-swagger-ui/images/**","/swagger-resources/configuration/*","/swagger-resources",//swagger请求
                            "/v2/api-docs"
                        ).permitAll()
                        // 对于获取token的rest api要允许匿名访问
                        .antMatchers("/auth/**").permitAll()
                        // 除上面外的所有请求全部需要鉴权认证。 .and() 相当于标示一个标签的结束,之前相当于都是一个标签项下的内容
                    .anyRequest().authenticated().and()
    
                    .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
    
            // 禁用缓存
            httpSecurity.headers().cacheControl();
        }
    
    }
    

    注意:这里找到被拦截的请求的方法就是使用谷歌浏览器的开发者工具栏查看有哪些请求被拦截,将这些被拦截的请求放行就可以了。

    第四步:在Controller层的方法上添加注解@ApiOperation和@ApiParam

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    @ApiOperation(value ="用户注册",notes = "用户注册",tags = {"auth"})
    public AbstractOutputDto register(@ApiParam(name = "用户注册",value = "传入JSON格式")@RequestBody AbstractInputDto<UserRegisterReqDto> abstractInputDto) throws AuthenticationException {
        UserRegisterReqDto userRegisterReqDto=abstractInputDto.getData();
        if(userRegisterReqDto.getCheckcode()!=null && userRegisterReqDto.getUltel()!=null){  //如果验证码和手机号都不为null
            AbstractOutputDto abstractOutputDto=authService.register(userRegisterReqDto);
            return abstractOutputDto;
            }
           return AbstractOutputDto.error("验证码或手机号不能为空!");
    }

    最终运行效果:

     

     

     

     

    展开全文
  • 转自:https://www.cnblogs.com/dyxd/p/7080026.html这里是实现自动化api稳当的生成,在网上看了很多swagger的文档,可能都是在为实现接口时直接使用的swagger,其实步骤差不多,但是更加详细的我还没看到,又或者说...

    转自:https://www.cnblogs.com/dyxd/p/7080026.html

    这里是实现自动化api稳当的生成,在网上看了很多swagger的文档,可能都是在为实现接口时直接使用的swagger,其实步骤差不多,但是更加详细的我还没看到,又或者说,我看着文档来的时候还是出错啦,绕了很大的弯,之前有听过要用这个,但是还是用过。接下来总结下我这次在使用过程中的步骤及一些问题。

    在接口已经成型的基础上集成swagger,实现了接口文档的自动化生成,相对于开发来说节约了写文档的大部分时间,无疑是一件莫大的好事情。接下来总结下这个过程:

    一、在现有Api的基础上添加Nuget包的引用(这里简述下现有api,不一定是webapi项目,要看接口实现在哪里,可以是类库,也可以是项目webapi等),有2个包,一个是Swagger.Net.UI,一个是Swashbuckle,如下图所示:

    (1)、Swagger.Net.UI的添加引用:

    (2)、Swashbuckled的添加引用

    这里的版本是4.5.2的版本,可能在4.0版本上就不一样啦,这里我没有尝试。。。

    二、安装成功后会有新增的文件如下所示:

                                     

    上面的因为前端的ui等都集成在dll中,所以SwaggerUI、App_Start下的SwaggerNet类都可以删除 ,然后主要是配置SwaggerConfig.cs文件。

    三、在设置的启动项目下生成XML文件,步骤如下:

    例如:我目前项目中有去实现接口的web项目,我就选择此“web项目”->“属性”->“生成”->勾选XML文件文件,如下如所示:

    然后点击保存,即可在bin文件下面找到此文件,可以自行去看下。

    四、修改App_Start文件夹下的SwaggerConfig文件

    (1)、添加注释

    打开App_Start文件夹下的SwaggerConfig文件,在方法Register把注释过的c.IncludeXmlComments(GetXmlCommentsPath());放开,然后在此类中增加方法GetXmlCommentsPath来获取生成文件的位置即可(又或者如下图,直接取XML文件也可)。而下面的路径是上面生成的XML文件的路径,而放开注释的那段代码实现了对XMl文件的读取,即添加注释,方法的实现如下:

    (2)、隐藏不需要的接口(即可以添加重复的接口)

    上面就是所有用到的,关于处理接口的代码,c.DocumentFilter();这个是为了实现过滤自己不需要的接口来设置的

    HiddenApiFilter这个类的实现如下:

    按 Ctrl+C 复制代码

    按 Ctrl+C 复制代码

    这个类为了方便可以直接在swaggerconfig类中,如下图所示:

    最后一步就是在我们不需要显示的接口类或者类内方法上面添加如下过滤器如下:

                  

    五、修改App_Start文件夹下的SwaggerNet文件,注释如下图的代码(我不知道为什么,如果不注释会报错的):

    注释代码如下:

    以上就是实现自动化的全部步骤,在地址栏中输入地址如下:即可看到如下的界面:

    过程就是这样的,可是做个小demo练习,我这个是直接在项目中添加啦。

    展开全文
  • 前言每次使用前端请求api地址都都要自己手写api地址过于繁琐创建genSwagger/index.js 文件当前genSwagger文件夹在根目录const fs = require('fs')const path = require('path')const http = require('http')function...

    前言

    每次使用前端请求api地址都都要自己手写api地址过于繁琐

    创建genSwagger/index.js 文件

    当前genSwagger文件夹在根目录

    const fs = require('fs')

    const path = require('path')

    const http = require('http')

    function mkdirsSync(dirname) {

    if (fs.existsSync(dirname)) {

    return true

    } else {

    if (mkdirsSync(path.dirname(dirname))) {

    fs.mkdirSync(dirname)

    return true

    }

    }

    }

    function getPath(pathUrl) {

    return path.resolve(__dirname, pathUrl)

    }

    function generateTemplate(arr) {

    return `import { ${arr.join(', ')} } from '@/utils/request'\n`

    }

    function generateFunc(name, summary, type = 'post') {

    const arr = name.slice(1).split('/')

    const fun = arr[arr.length - 1]

    return `

    // ${summary || ''}

    export function ${fun}(data, cb, errHandle) {

    return ${type}('${name}', data, cb, errHandle)

    }\n`

    }

    function httpgetJson(url) {

    return new Promise((resolve, reject) => {

    http.get(url, (res) => {

    const { statusCode } = res

    const contentType = res.headers['content-type']

    let error

    if (statusCode !== 200) {

    error = new Error('请求失败。\n' +

    `状态码: ${statusCode}`)

    } else if (!/^application\/json/.test(contentType)) {

    error = new Error('无效的 content-type.\n' +

    `期望 application/json 但获取的是 ${contentType}`)

    }

    if (error) {

    console.error(error.message)

    // 消耗响应数据以释放内存

    res.resume()

    return

    }

    res.setEncoding('utf8')

    let rawData = ''

    res.on('data', (chunk) => {

    rawData += chunk

    })

    res.on('end', () => {

    try {

    const parsedData = JSON.parse(rawData)

    resolve(parsedData)

    } catch (e) {

    reject(`错误: ${e.message}`)

    }

    })

    }).on('error', (e) => {

    reject(`错误: ${e.message}`)

    })

    })

    }

    const srcFolder = '/src'

    const url = 'http://localhost:61793/swagger/v1/swagger.json'

    // const argv = process.argv

    // console.log(argv)

    async function main() {

    console.log('获取远程json文件中...')

    const { paths } = await httpgetJson(url)

    console.log('获取成功正在生成api文件')

    const obj = {}

    for (const name in paths) {

    const path = paths[name]

    let folder = ''

    if (path.post) {

    const tag = path.post.tags[0]

    if (!tag) continue

    const urlArray = name.slice(1).split('/')

    if (name.slice(1).split('/').length === 4) {

    folder = urlArray[1]

    } else {

    if (name.slice(1).split('/')[0] !== tag) continue

    }

    if (obj[path.post.tags[0]]) {

    obj[path.post.tags[0]].push({ summary: path.post.summary, tag, name, type: 'post', folder })

    } else {

    obj[path.post.tags[0]] = [{ summary: path.post.summary, tag, name, type: 'post', folder }]

    }

    } else if (path.get) {

    const tag = path.get.tags[0]

    console.log(tag)

    if (!tag) continue

    const urlArray = name.slice(1).split('/')

    if (name.slice(1).split('/').length === 4) {

    folder = urlArray[1]

    } else {

    if (name.slice(1).split('/')[0] !== tag) continue

    }

    if (obj[path.get.tags[0]]) {

    obj[path.get.tags[0]].push({ summary: path.get.summary, tag, name, type: 'get', folder })

    } else {

    obj[path.get.tags[0]] = [{ summary: path.get.summary, tag, name, type: 'get', folder }]

    }

    }

    }

    for (const tagName in obj) {

    let jsString = ''

    const requestTypes = []

    let folder = ''

    for (const item of obj[tagName]) {

    const requestType = requestTypes.filter(o => o === item.type)

    if (requestType.length === 0) requestTypes.push(item.type)

    jsString += generateFunc(item.name, item.summary, item.type)

    folder = item.folder

    }

    jsString = generateTemplate(requestTypes) + jsString

    mkdirsSync(getPath(`..${srcFolder}/api/${folder}`))

    // console.log(jsString)

    fs.writeFileSync(getPath(`..${srcFolder}/api/${folder}/${tagName}.js`), jsString)

    }

    console.log('生成完毕')

    }

    main()

    我目前url格式是 /Api/Admin/Home/Index 和格式 /Test/Index

    生成后的文件夹格式是/api/Admin/Home.js 或/api/Test.js 文件如下

    import { get, post } from '@/utils/request'

    // 获取

    export function Index(data, cb, errHandle) {

    return get('/Api/Admin/Home/Index', data, cb, errHandle)

    }

    // 添加

    export function Add(data, cb, errHandle) {

    return post('/Api/Admin/Home/Add', data, cb, errHandle)

    }

    // 删除

    export function Delete(data, cb, errHandle) {

    return post('/Api/Admin/Home/Delete', data, cb, errHandle)

    }

    使用时需要将const url = 'http://localhost:61793/swagger/v1/swagger.json'改成你自己的地址

    当前项目目录结构基于element-admin-template

    修改package.json文件

    在scripts索引中加入"swagger":"node genSwagger/index.js"

    "scripts": {

    "dev": "vue-cli-service serve",

    "build:prod": "vue-cli-service build",

    "build:stage": "vue-cli-service build --mode staging",

    "preview": "node build/index.js --preview",

    "lint": "eslint --ext .js,.vue src",

    "test:unit": "jest --clearCache && vue-cli-service test:unit",

    "test:ci": "npm run lint && npm run test:unit",

    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",

    "swagger": "node genSwagger/index.js"

    }

    使用npm run swagger 命令生成swagger接口请求文件

    展开全文
  • 前端同学每次查询该文档称为某个接口。相当于,我们从swagger-ui上摘录接口使用方法,想象大家在开发过程中是否遇见到过以下问题: 调用接口发现接口报404,费心费力检查发现把单词拼错了〜 调用接口发现接口报400,...
  • 我们可以根据swagger接口文档,前端来自动生成接口方法 根据swagger.json文件来npm 生成接口方法 接口信息都截去了 大概数据结构如下我们主要需要用到的是path里的 path: { "/api/****/Login": { "post": { ...
  • --Swagger-UI API文档生产工具--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> &...
  • Swagger—构建API文档

    2021-07-22 10:21:10
    Swagger 一、描述 现代化的研发 组织 架构中,一个研发团队基本包括了 产品组、后端组、前端组、APP端研发、 测试组、 UI 组等,各个细分组织人员各司其职,共同完成产品的全周期工作。如何进行组织架构内的有效...
  • Swagger 导出API

    2018-12-09 15:30:00
    Swagger 导出API 这算是在博客园的第一篇博客吧,之后发的应该也会同步到博客园上。 此前的博客地址: https://blog.mytyiluo.cn Swagger简介 Swagger是一个开源软件框架,可帮助开发人员设计,构建,记录和使用...
  • Spring Boot集成Swagger 2实现API接口管理

    千次阅读 2018-05-04 08:53:09
    随着微服务架构体系的发展和应用, 为了前后端能够更好的集成与对接,同时为了项目的方便交付,每个项目都需要提供相应的API文档。传统的API文档编写存在多个痛点。
  • Java Swagger实现前端不同版本api显示,后端自定义多包扫描
  • SpringBoot + Swagger + RESTful API实战详解

    千次阅读 2019-02-18 11:16:00
    SpringBoot简单介绍已经有一篇相关博客,大家可以参考这里,本篇博客主要SpringBoot实战Swagger与RESTful的开发。接下来进入正题: ...对于Swagger的理解,其实就是一个工具,是一个构建API的工具。根据Contro...
  • Swagger注释@API详细说明

    千次阅读 2019-12-22 22:30:18
    前言: 相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,...swagger是当前最好用的Restful API文档生成的...
  • 利用swagger生成api接口文档

    千次阅读 2019-06-07 23:55:03
    1. swagger出现的背景? 现在的网站架构,前后端分离已经成为一种趋势,前后端的技术在各自的道路上越走远越...联系前端和后端的主要纽带就是约定好的api文档。但在实际开发中往往api文档不能及时更新,带来一些问题...
  • 由于存在多终端的情况(移动端,web前端,小程序等),所以我们会抽象出RESTful API并共用一些底层业务代码。 由于接口众多,并且细节复杂,所以催生了一些api框架,Swagger就凭借其使用简单、...
  • Swagger是当前最好用的Restful API文档生成的开源项目,通过swagger-spring项目 实现了与SpingMVC框架的无缝集成功能,方便生成spring restful风格的接口文档, 同时swagger-ui还可以测试spring restful风格的接口...
  • swagger2 导出api为html和word文档

    千次阅读 2020-08-26 16:48:26
    swagger2 导出api为html和word文档 参考地址 https://blog.csdn.net/zhuyu19911016520/article/details/85048271 依赖引入 <dependency> <groupId>io.springfox</groupId> <artifactId&...
  • 如果不选择多租户, ABP生成的sample并没有把后台逻辑包装成RESTFul api, 而是mvc前端直接dll引用application service。我们需要做2点改动:1.把mvc改成web api host, 然后添加swagger的描述2.把application ...
  • 前言:WebApi接口开发完毕后,交付给前端人员或手机端开发者时接口说明文档是必不可少的配套设备,如果公司流程不规范大家使用口口相传的交接方式,而且没有改进的欲望,那你可以到此为止了。Swagger是方便测试接口...
  • 相信很多后端开发在项目中都会碰到要写 api 文档,不管是给前端、移动端等提供更好的对接,还是以后为了以后交接方便,都会要求写 api 文档。 而手写 api 文档的话有诸多痛点: 文档更新的时候,需要再次发送给对接...
  • 如上一篇博客所说,好的文档系统对API Server至关重要,本文介绍在Express框架中使用Swagger构建一个良好的项目文档系统的基本流程,同时明确一些实践过程中肯定会遇到的问题的解决方案。本文遵循Swagger 2.0使用...
  • 关于IDEA配置Swagger自动生成API

    万次阅读 2019-03-17 16:14:06
    前两天学习了一下Swagger自动生成API的方法。然后就有一些自己的总结,感兴趣的可以看看。 我们要了解swagger,我们就要先从前后端分离去入手。按照现在的发展趋势,可以说前后端分离已经是业内对开发和部署方式所...
  • 在遇到前端小姐姐/测试小姐姐要接口文档的时候是不是特别难受香菇。今天就来说说解救广大后端人员的福音。 一,Swagger2集成jar引入(我们用maven管理jar) pom增加: <dependency> <groupId>io....
  • go实践之swagger自动生成api文档

    万次阅读 2018-12-08 21:12:45
    作为一个后端开发,给前端提供api接口是必须的。手动去写文档不是一个程序员的风格。swagger就是一个很好的api文档生成该工具,go当然也支持了。下面看看怎么使用这个工具。 1、安装需要用到的包 root@localhos...
  • 而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。 这样一来,我们的RESTful API就有可能要面对多个开发人员...
  • swaggerAPI接口文档分组

    千次阅读 2020-02-17 21:23:26
    swagger是一个深度集成的后台API文档工具,极大的方便了后端的开发测试以及和前端的对接工作。但是当项目中的接口越来越多时,会导致页面上的接口过多,查看起来不是很方便,这时可以使用swagger的分组功能将接口进行...
  • 前言:为了分工明确,高效研发,中大型应用往往采用前后端完全分离方案,前端同学只负责前端部分开发,后端同学只负责后端开发,但开发完成之后,前端需要从后端api调取数据,联调之后才能完成最终的开发工作,这...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,261
精华内容 2,504
关键字:

swagger前端获取api