• Spring Boot集成Springfox Swagger3和简单应用


    摘要:Springfox Swagger可以动态生成 API 接口供前后端进行交互和在线调试接口,Spring Boot 框架是目前非常流行的微服务框架,所以,在Spring Boot 项目中集成Springfox非常有意义。介绍Spring Boot集成Springfox Swagger3及swagger的简单应用。

    §前言

      Swagger是什么?官方说法:Swagger是一个规范和完整的框架,用于创建、描述、调试和可视化 RESTful 风格的 Web 服务。通俗地说,Swagger 是一个主要用来在线创建文档的插件,主要用来高质量地动态生成 API 接口供前后端进行交互和在线调试接口,如果不生成的话就需要写静态文档来交互,那样不仅速度慢而且不容易修改。发现了痛点就要寻找解决方案,故Swagger应运而生。

      Springfox Swagger是Spring 基于swagger规范,可以将基于SpringMVC和Spring Boot项目的源码自动生成JSON格式的描述文件。本身不是属于Swagger官网提供的。Spring Boot 框架是目前非常流行的微服务框架,所以,在Spring Boot 项目中集成Springfox非常有意义,可以保证及时更新API文档,降低前后端沟通成本,提高系统迭代效率。

      本文所用软件开发环境如下:

      ♦ Java version 13.0.1
      ♦ IntelliJ IDEA 2019.3.2 (Ultimate Edition)
      ♦ Spring Boot 2.3.1.RELEASE

    §Spring Boot 集成 Springfox Swagger3

      若想为Spring Boot项目添加无需任何配置的springfox,需引入其maven依赖库:

            <!--集成 springfox swagger3 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-boot-starter</artifactId>
                <version>3.0.0</version>
            </dependency>
    

      为了便于管理API文档,建议编写一个Swagger配置类,这里的配置类如下:

    import org.springframework.beans.factory.annotation.Value;
    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.oas.annotations.EnableOpenApi;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    
    /**
     * Swagger 配置类
     *
     * @author Wiener
     * @date 2021/2/26
     */
    @EnableOpenApi
    @Configuration
    public class SwaggerConfig {
        //读取application.properties 文件设置的是否开启swagger属性,正式环境一般需要关闭
        @Value(value = "${swagger.enabled}")
        Boolean swaggerEnabled;
    
        @Bean
        public Docket createRestApi() {
            return new Docket(DocumentationType.OAS_30).apiInfo(apiInfo())
                    // 是否开启swagger
                    .enable(swaggerEnabled).select()
                    // 过滤条件,扫描指定路径下的文件
                    .apis(RequestHandlerSelectors.basePackage("com.eg.wiener.controller"))
                                    //只保留/user/*风格的路径,大家可以调试一下
    //                .paths(PathSelectors.ant("/user/*"))
                    // 指定路径处理,PathSelectors.any()代表不过滤任何路径
                    .paths(PathSelectors.any())
                    .build().pathMapping("/");
        }
    
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("Spring Boot集成Springfox Swagger示例")
                    .description("楼兰胡杨")
                    // 开发者信息
                    .contact(new Contact("楼兰胡杨", "https://www.cnblogs.com/east7/", "wienerXXX@163.com"))
                    .version("1.0.0")
                    .build();
        }
    }
    

      注解@EnableOpenApi用于开启Swagger的自动配置,如果没加的话,自然而然也就看不到后面的swagger UI面板了。通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger UI面板;在 Docket 上添加筛选条件。Docket 类提供了 apis() 和 paths() 两个方法来帮助我们在不同级别上过滤接口:

    • apis() :通过指定扫描路径的方式,让 Swagger 只去某些路径下面扫描文件。
    • paths() :通过筛选 API 的 url 进行过滤。

      在上面的Swagger 配置类SwaggerConfig中,我们定义了 Docket 实例的 apis() 和 paths(),那么,swagger接口文档界面将只会展示包com.eg.wiener.controller中的API。关于PathSelectors.ant()的用法,各位同仁可以调试一下,由于时间有限,未曾验证是否可用。

      另一种解决方案就是使用@ApiIgnore注解屏蔽某些API。如果想在API文档中屏蔽掉某个接口,那么只需要在这个接口上加上@ApiIgnore 即可。

    丰富文档内容

      在完成了上述配置后,已经算是初步集成Springfox Swagger3,可以启动服务查看API文档内容了。但是这样的文档主要针对请求本身,描述信息的主要来源是函数的命名,对用户并不友好,我们通常需要使用swagger注解增加一些说明文字来使得API文档内容更加丰满。Swagger中常用的注解及其说明:

    @Api:用在类上,说明该类的作用。
    @ApiOperation:为API增加方法说明。
    @ApiImplicitParams : 用在方法上包含一组参数说明。
    @ApiImplicitParam:给方法入参增加说明。
    @ApiResponses:用于表示一组响应
    @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
        l   code:数字,例如400
        l   message:信息,例如"必填参数不可为空"
        l   response:抛出异常的类   
    @ApiModel:描述一个Model的信息(一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候)
        l   @ApiModelProperty:描述一个model的属性

    案例分析

      修改API实体类User,添加swagger注解:

    @Setter
    @Getter
    @ToString
    @ApiModel("用户实体")
    public class User implements Serializable {
    
        private static final long serialVersionUID = -8842370047277749376L;
        @ApiModelProperty("用户 id")
        private Long id;
        @ApiModelProperty("用户姓名")
        private String userName;
        private Integer age;
        private String address;
        private String mobilePhone;
        private String remark;
    
        public User() {
        }
        public User(Long id, String userName, Integer age) {
            this.id = id;
            this.userName = userName;
            this.age = age;
        }
    }
    

      在实体类使用注解@ApiModel和 @ApiModelProperty可以添加属性备注,这些备注信息将展示在swagger页面的Schema中,效果如下:

      在 controller 包下新建 UserController.java 类,通过在控制器类上增加 @Api 注解,可以给控制器添加标签信息。通过在接口方法上增加 @ApiOperation 注解来添加对接口的描述。关于swagger注解的更多信息,这里就不再阐述,需要的话,请去问问度娘。

    /**
     * @author Wiener
     */
    @RestController
    @RequestMapping("/user")
    @Api(tags="用户API")
    public class UserController {
    
        private static Logger logger = LoggerFactory.getLogger(UserController.class);
    
        /**
         * 同时使用 @RequestBody 与 @RequestParam()
         * http://localhost:8087/wiener/user/addUser?token=IamToken
         * @param user
         * @param token
         * @return
         * @throws Exception
         */
        @PostMapping("/addUser")
        @ApiOperation(value="用户新增")
        public User addUser(@RequestBody User user, @RequestParam("token") String token) throws Exception {
            user.setRemark(token);
            return user;
        }
        /**
         * 示例地址 http://localhost:8087/wiener/user/getUser?id=9996669
         * @return
         * @throws Exception
         */
        @GetMapping("/getUser")
        @ApiOperation(value="用户查询(ID)")
        @ApiImplicitParam(name="id",value="查询ID",required=true)
        public User getUser(Long id) throws Exception {
            logger.info("--------------------");
            User user = new User();
            user.setId(id);
            user.setAddress("测试地址是 " + UUID.randomUUID().toString());
            logger.info("类信息: {}", user.getClass());
            return user;
        }
    }
    

      这个时候已经算是进一步集成Springfox-Swagger3了,启动项目后访问http://IP:port/your-app-root/swagger-ui/index.html可以看到我们的swagger文档界面,其中,IP表示服务器IP地址,port表示项目配置的端口号,your-app-root表示项目配置的根路径。在我的项目中,其访问路径是http://127.0.0.1:8087/wiener/swagger-ui/index.html,在浏览器访问此URL进入如下文档界面:

    使用 SwaggerUI访问API

      找到用户查询API getUser并进入接口详情页面,可以在详情页面右侧看到** Try it out** 按钮,单击此按钮即可进入接口调用界面,在id输入框随机输入一个Long类型的数字,单击执行即可请求getUser方法:

      从API返回值可以得出结论:使用 Swagger UI 成功访问了API,故集成集成Springfox Swagger3完毕。有底气甩了Postman了,你认为呢?

    §小结

      Springfox既可以减少创建文档的工作量,同时接口文档又可以融合到代码之中去,使维护API文档和修改代码同步进行,让我们在修改代码逻辑的同时方便的修改文档说明,这太酷了。另外,Swagger UI界面页提供了强大的页面测试功能来调试每个RESTful API。欢迎点赞阅读,一同学习交流;若有疑问,请在文章下方留下你的神评妙论!

    §Reference


      读后有收获,小礼物走一走,请作者喝咖啡。

    赞赏支持

  • 相关阅读:
    BZOJ 3625: [Codeforces Round #250]小朋友和二叉树
    HDU 2069 Coin Change
    HDU 1709 The Balance
    HDU 1398 Square Coins
    HDU 1171 Big Event in HDU
    HDU 1085 Holding Bin-Laden Captive!
    BZOJ 3167: [Heoi2013]Sao
    BZOJ 1408: [Noi2002]Robot
    BZOJ 3163: [Heoi2013]Eden的新背包问题
    【Tsinsen-A1486】树(王康宁) 点分治 + Trie
  • 原文地址:https://www.cnblogs.com/east7/p/14454028.html
Copyright © 2020-2023  润新知