zoukankan      html  css  js  c++  java
  • 接口文档:第二章:使用Swagger接口的文档在线自动生成

    上一章:商城接口文档:第一章:简洁版接口文档。花了二天搞了一个比较简洁的接口文档,浪费时间不说,写的也不太好,不满意。这一章使用Swagger接口的文档在线自动生成省下不少时间,而且很规范。

    导入Maven

    版本号请根据实际情况自行更改。

    <dependency>

        <groupId>io.springfox</groupId>

        <artifactId>springfox-swagger2</artifactId>

        <version>2.2.2</version>

    </dependency>

    <dependency>

        <groupId>io.springfox</groupId>

        <artifactId>springfox-swagger-ui</artifactId>

        <version>2.2.2</version>

    </dependency>

    自定义注释生成器

    package com.macro.mall;
    
    import org.mybatis.generator.api.IntrospectedColumn;
    import org.mybatis.generator.api.IntrospectedTable;
    import org.mybatis.generator.api.dom.java.CompilationUnit;
    import org.mybatis.generator.api.dom.java.Field;
    import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
    import org.mybatis.generator.internal.DefaultCommentGenerator;
    import org.mybatis.generator.internal.util.StringUtility;
    
    import java.util.Properties;
    
    /**
     * 自定义注释生成器
     * Created by macro on 2018/4/26.
     */
    public class CommentGenerator extends DefaultCommentGenerator {
        private boolean addRemarkComments = false;
        private static final String EXAMPLE_SUFFIX="Example";
        private static final String API_MODEL_PROPERTY_FULL_CLASS_NAME="io.swagger.annotations.ApiModelProperty";
    
        /**
         * 设置用户配置的参数
         */
        @Override
        public void addConfigurationProperties(Properties properties) {
            super.addConfigurationProperties(properties);
            this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments"));
        }
    
        /**
         * 给字段添加注释
         */
        @Override
        public void addFieldComment(Field field, IntrospectedTable introspectedTable,
                                    IntrospectedColumn introspectedColumn) {
            String remarks = introspectedColumn.getRemarks();
            //根据参数和备注信息判断是否添加备注信息
            if(addRemarkComments&&StringUtility.stringHasValue(remarks)){
    //            addFieldJavaDoc(field, remarks);
                //数据库中特殊字符需要转义
                if(remarks.contains(""")){
                    remarks = remarks.replace(""","'");
                }
                //给model的字段添加swagger注解
                field.addJavaDocLine("@ApiModelProperty(value = ""+remarks+"")");
            }
        }
    
        /**
         * 给model的字段添加注释
         */
        private void addFieldJavaDoc(Field field, String remarks) {
            //文档注释开始
            field.addJavaDocLine("/**");
            //获取数据库字段的备注信息
            String[] remarkLines = remarks.split(System.getProperty("line.separator"));
            for(String remarkLine:remarkLines){
                field.addJavaDocLine(" * "+remarkLine);
            }
            addJavadocTag(field, false);
            field.addJavaDocLine(" */");
        }
    
        @Override
        public void addJavaFileComment(CompilationUnit compilationUnit) {
            super.addJavaFileComment(compilationUnit);
            //只在model中添加swagger注解类的导入
            if(!compilationUnit.isJavaInterface()&&!compilationUnit.getType().getFullyQualifiedName().contains(EXAMPLE_SUFFIX)){
                compilationUnit.addImportedType(new FullyQualifiedJavaType(API_MODEL_PROPERTY_FULL_CLASS_NAME));
            }
        }
    }
    

    创建Swagger2配置类

    在Application.java同级创建Swagger2的配置类Swagger2

    package com.swaggerTest;
     
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
     
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
     
    /**
     * Swagger2配置类
     * 在与spring boot集成时,放在与Application.java同级的目录下。
     * 通过@Configuration注解,让Spring来加载该类配置。
     * 再通过@EnableSwagger2注解来启用Swagger2。
     */
    @Configuration
    @EnableSwagger2
    public class Swagger2 {
        
        /**
         * 创建API应用
         * apiInfo() 增加API相关信息
         * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
         * 本例采用指定扫描的包路径来定义指定要建立API的目录。
         * 
         * @return
         */
        @Bean
        public Docket createRestApi() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.swaggerTest.controller"))
                    .paths(PathSelectors.any())
                    .build();
        }
        
        /**
         * 创建该API的基本信息(这些基本信息会展现在文档页面中)
         * 访问地址:http://项目实际地址/swagger-ui.html
         * @return
         */
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("Spring Boot中使用Swagger2构建RESTful APIs")
                    .description("更多请关注http://www.baidu.com")
                    .termsOfServiceUrl("http://www.baidu.com")
                    .contact("sunf")
                    .version("1.0")
                    .build();
        }
    }

    通过createRestApi函数创建Docket的Bean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。

    Swagger使用的注解及其说明:

    @Api:用在类上,说明该类的作用。

    @ApiOperation:注解来给API增加方法说明。

    @ApiImplicitParams : 用在方法上包含一组参数说明。

    @ApiImplicitParam:用来注解来给方法入参增加说明。

    @ApiResponses:用于表示一组响应

    @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息

        l   code:数字,例如400

        l   message:信息,例如"请求参数没填好"

        l   response:抛出异常的类   

    @ApiModel:描述一个Model的信息(一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候)

        l   @ApiModelProperty:描述一个model的属性

    注意:@ApiImplicitParam的参数说明:

    paramType:指定参数放在哪个地方

    header:请求参数放置于Request Header,使用@RequestHeader获取

    query:请求参数放置于请求地址,使用@RequestParam获取

    path:(用于restful接口)-->请求参数的获取:@PathVariable

    body:(不常用)

    form(不常用)

    name:参数名

    dataType:参数类型

    required:参数是否必须传

    true | false

    value:说明参数的意思

    defaultValue:参数的默认值

    案例1:

    package com.swaggerTest.controller;
     
    import org.springframework.stereotype.Controller;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
     
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
     
    /**
     * 一个用来测试swagger注解的控制器
     * 注意@ApiImplicitParam的使用会影响程序运行,如果使用不当可能造成控制器收不到消息
     * 
     * @author SUNF
     */
    @Controller
    @RequestMapping("/say")
    @Api(value = "SayController|一个用来测试swagger注解的控制器")
    public class SayController {
        
        @ResponseBody
        @RequestMapping(value ="/getUserName", method= RequestMethod.GET)
        @ApiOperation(value="根据用户编号获取用户姓名", notes="test: 仅1和2有正确返回")
        @ApiImplicitParam(paramType="query", name = "userNumber", value = "用户编号", required = true, dataType = "Integer")
        public String getUserName(@RequestParam Integer userNumber){
            if(userNumber == 1){
                return "张三丰";
            }
            else if(userNumber == 2){
                return "慕容复";
            }
            else{
                return "未知";
            }
        }
        
        @ResponseBody
        @RequestMapping("/updatePassword")
        @ApiOperation(value="修改用户密码", notes="根据用户id修改密码")
        @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "userId", value = "用户ID", required = true, dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "password", value = "旧密码", required = true, dataType = "String"),
            @ApiImplicitParam(paramType="query", name = "newPassword", value = "新密码", required = true, dataType = "String")
        })
        public String updatePassword(@RequestParam(value="userId") Integer userId, @RequestParam(value="password") String password, 
                @RequestParam(value="newPassword") String newPassword){
          if(userId <= 0 || userId > 2){
              return "未知的用户";
          }
          if(StringUtils.isEmpty(password) || StringUtils.isEmpty(newPassword)){
              return "密码不能为空";
          }
          if(password.equals(newPassword)){
              return "新旧密码不能相同";
          }
          return "密码修改成功!";
        }
    }

    完成上述代码添加上,启动Spring Boot程序,访问:http://localhost:8080/swagger-ui.html

    如上图,可以看到暴漏出来的控制器信息,点击进入可以看到详细信息。

    两个注意点:

    1.  paramType会直接影响程序的运行期,如果paramType与方法参数获取使用的注解不一致,会直接影响到参数的接收。

    例如:

    使用Sawgger UI进行测试,接收不到!

    2.  还有一个需要注意的地方:

    Conntroller中定义的方法必须在@RequestMapper中显示的指定RequestMethod类型,否则SawggerUi会默认为全类型皆可访问, API列表中会生成多条项目。

    如上图:updatePassword()未指定requestMethod,结果生成了7条API信息。所以如果没有特殊需求,建议根据实际情况加上requestMethod。

  • 相关阅读:
    K2路由器刷机教程
    GitBook Editor使用教程
    source tree使用教程
    github与github网站push神器
    tgp助手开启逆战游戏无反应
    如何计算服务器指标参数
    排序--堆排序算法
    排序--希尔排序算法
    排序--直接插入排序算法
    排序--冒泡排序算法
  • 原文地址:https://www.cnblogs.com/javawxid/p/12811956.html
Copyright © 2011-2022 走看看