zoukankan      html  css  js  c++  java
  • SpringBoot之整合Swagger2

    一、问题描述

    随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染、先后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远。 前端和后端的唯一联系,变成了API接口;API文档变成了前后端开发人员联系的纽带,变得越来越重要,swagger就是一款让你更好的书写API文档的框架,而且swagger可以完全模拟http请求,入参出参和实际情况差别几乎为零。

      没有API文档工具之前,大家都是手写API文档的(维护起来相当困难),在什么地方书写的都有,有在confluence上写的,有在对应的项目目录下readme.md上写的,每个公司都有每个公司的玩法,无所谓好坏。但是能称之为“框架”的,估计也只有swagger了

    二、使用步骤

    1. 创建springboot项目配置pom.xml
    <dependency>
    			<!--添加lombok就可以不用再写set,get方法-->
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.9.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.9.2</version>
            </dependency>
    
    1. 配置启动类
    package com.example;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    
    
    1. 创建Swagger的配置类
    package com.example.config;
    
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
    
        @Autowired
        Environment environment;
        //配置Docket以配置Swagger具体参数
    
        //在不同生产模式下的操作,
    //    @Bean
    //    public Docket docket(){
    //        Profiles profiles=Profiles.of("dev","test");
    //        boolean isEnable = environment.acceptsProfiles(profiles);
    //        return new Docket(DocumentationType.SWAGGER_2)
    //                .ignoredParameterTypes(Integer.class,Long.class, HttpSession.class)
    //                .enable(isEnable);
    //    }
    
    
    //    @Bean
    //    public Docket docketUser(){
    //        Parameter token= new ParameterBuilder().name("token")
    //                .description("用户登录令牌")
    //                .parameterType("header")
    //                .modelRef(new ModelRef("String"))
    //                .required(true)
    //                .build();
    //        List<Parameter> parameters=new ArrayList<>();
    //        parameters.add(token);
    //        return new Docket(DocumentationType.SWAGGER_2)
    //                .globalOperationParameters(parameters);
    //    }
    
    
        //基于包
        @Bean
        public Docket docket(){
            return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
    //        return new Docket(DocumentationType.SWAGGER_2)
    //                .select()
    //                .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
    //                //paths可以进行筛选想要的方法
    //                .paths(PathSelectors.ant("/hello/**"))
    //                .build();
        }
    
        //基于方法
    //    @Bean
    //    public Docket docket(){
    //        return new Docket(DocumentationType.SWAGGER_2)
    //                .select()
    //                .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class)).build();
    //    }
    
        private ApiInfo apiInfo(){
            Contact contact=new Contact("小谢","aaa.com","1787798327@qq.com");
            return new ApiInfo("Swagger学习接口文档",
                    "这是学习swagger时生成的文档信息",
                    "v1.0",
                    "http://xietongxue.top:8090",
                    contact,
                    "",
                    "",
                    new ArrayList<>()
            );
        }
    
    
    
    }
    
    

    1

    1. 创建User
    package com.example.model;
    
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ApiModel("用户实体")
    public class User {
        @ApiModelProperty(value = "用户id",example = "0")
        private Integer id;
        @ApiModelProperty("用户名")
        private String username;
        @ApiModelProperty(value = "用户年龄",example = "1")
        private String age;
    }
    
    1. 创建Controller
    package com.example.controller;
    
    import com.example.model.User;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.web.bind.annotation.*;
    
    @Api(tags = "用户相关的请求")
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @ApiOperation("获取用户信息")
        @ApiImplicitParams({
                @ApiImplicitParam(name = "username",value = "用户名",
                        dataType = "string",paramType = "header",defaultValue = "zhangsan",example = "lisi"),
                @ApiImplicitParam(name = "password",value = "用户密码")
        })
    
        @GetMapping
        public String getUser(String username,String password){
            return "user";
        }
    
        @ApiOperation("添加用户")
        @PostMapping
        public User postUser(User user){
            return user;
        }
    
        @ApiOperation("删除用户")
        @DeleteMapping
        public User delUser(@RequestBody User user){
            return user;
        }
    
    
    
    
    //    @GetMapping
    //    public String getUser(){
    //        return "张三";
    //    }
    //
    //    @PostMapping
    //    public String addUser(String username){
    //        return username;
    //    }
    //
    //    @DeleteMapping
    //    public User delUser(){
    //        User zs = new User("张三", "15");
    //        return zs;
    //    }
    //
    //    @PutMapping
    //    public String putUser(@RequestBody User user){
    //        return "user";
    //    }
    }
    
    

    2
    6. 启动测试http://localhost:8080/swagger-ui.html
    在这里插入图片描述

    部分代码精讲

    除了通过包路径配置扫描接口外,还可以通过配置其他方式扫描接口,这里注释一下所有的配置方式:

    any() // 扫描所有,项目中的所有接口都会被扫描到
    none() // 不扫描接口
    withMethodAnnotation(final Class<? extends Annotation> annotation)// 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
    withClassAnnotation(final Class<? extends Annotation> annotation) // 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
    basePackage(final String basePackage) // 根据包路径扫描接口
    
    

    1、配置接口扫描过滤
    上述方式可以通过具体的类、方法等扫描接口,还可以配置如何通过请求路径配置:

    eturn new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller"))
                    // 配置如何通过 path过滤 即这里只扫描 请求以 /user开头的接口
        		   .paths(PathSelectors.ant("/user/**"))
                    .build();
    
    

    这里的可选值还有:

    any() // 任何请求都扫描
    none() // 任何请求都不扫描
    regex(final String pathRegex) // 通过正则表达式控制,返回true扫描,false不扫描
    ant(final String antPattern) // 通过ant()表达式控制,返回true扫描,false不扫描
    
    

    2、配置要忽略的请求参数
    可以通过ignoredParameterTypes()方法去配置要忽略的参数:

    // 配置docket以配置Swagger具体参数
        @Bean
        public Docket docket() {
            return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                // 配置要忽略的参数
                    .ignoredParameterTypes(HttpServletRequest.class) 
                    .select()
           .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
        }
    
    
    

    3、配置是否启动Swagger
    通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了:

    @Bean
        public Docket docket() {
            return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                    .ignoredParameterTypes(HttpServletRequest.class)
                    .enable(false) // 配置是否启用Swagger,如果是false,在浏览器将无法访问
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
        }
    
    

    **4、如何动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示?
    **

    @Bean
        public Docket docket(Environment environment) {
            // 设置要显示swagger的环境
            Profiles of = Profiles.of("dev", "test");
            // 判断当前是处于该环境,通过 enable() 接收此参数判断是否要显示
            boolean b = environment.acceptsProfiles(of);
    
            return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                    .ignoredParameterTypes(HttpServletRequest.class)
                    .enable(b) // 配置是否启用Swagger,如果是false,在浏览器将无法访问
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
        }
    
    

    5、配置API分组
    如果没有配置分组,默认是default。通过groupName()方法即可配置分组:

     //配置分组
        @Bean
        public Docket docketUser(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .groupName("用户")
                    .select().paths(PathSelectors.ant("/user")).build();
        }
    
        @Bean
        public Docket docketHello(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .groupName("你好")
                    .select().paths(PathSelectors.ant("/hello")).build();
        }
    
    

    如下图所示,我们配置了groupName("user")那么当前接口分组信息为user。
    4

    6、实体配置
    比如当前项目中有这么一个实体:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ApiModel("用户实体")
    public class User {
        @ApiModelProperty(value = "用户id",example = "0")
        private Integer id;
        @ApiModelProperty("用户名")
        private String username;
        @ApiModelProperty(value = "用户年龄",example = "1")
        private String age;
    }
    

    只要这个实体在请求接口的返回值上(即使是泛型),都能映射到实体项中:

    5
    注:并不是因为@ApiModel这个注解让实体显示在这里了,而是只要出现在接口方法的返回值上的实体都会显示在这里,而@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的。
    @ApiModel为类添加注释
    @ApiModelProperty为类属性添加注释

    常用的注解

    swagger通过注解表明该接口文档会生成文档,包括接口名,请求方法,参数,返回信息的等等。
    @Api修饰整个类,描述controller的作用
    @ApiOperation:描述一个类的一个方法,或者说一个接口
    @ApiParam:单个参数描述
    @ApiModel:当接收参数为对象时
    @ApiProperty:用对象接收参数时,描述对象的一个字段
    @ApiRespose:HTTP响应其中1个描述
    @ApiResponses:HTTP响应整体描述
    @ApiIgnore:使用该注解忽略这个API
    @ApiError:发生错误返回的信息
    @ApiImplicitParam:一个参数请求
    @ApiImplicitParams:多个请求
    详细解释:
    @Api:用在请求类上,表示对类的说明
    tags=“说明该类的作用,可以在UI界面上看到的注解”
    value=“该参数没什么意义,在UI界面上也看到,所以不需要配置”
    @ApiOperation:用在请求的方法上,说明方法的用途,作用
    value=“说明方法的用途,作用”
    notes=“方法的备注说明”
    @ApiImplicitParams:用在请求的方法上,表示一组参数的说明
    @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
    name:参数名
    value:参数的汉字说明
    required:参数放在哪个地方
    
    header:请求参数的获取 @RequestHeader
    query:请求参数的获取 @RequestParam
    path:(用于Restful接口)
    body(不常用)
    form(不常用)
    dataTye:当参数为对象类型时指定参数类型
    @ApiResponses:用在请求的方法上,表示一组响应
    @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息(实际上任何相应信息都可以)
    code:数字,例如400
    message:信息,例如“请求参数没填写正确”
    response:抛出的异常类
    
    @ApiModel:用于响应类上,表示一个返回响应数据的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParams注解进行描述的时候)
    @ApiModelProperty:用在属性上,描述响应类的属性
    
  • 相关阅读:
    闭包和this
    闭包与变量
    闭包
    ES6扩展运算符的几个小技巧
    js对象的深拷贝
    js获取当前点击元素的索引
    前端学习指北
    css实现心形图案
    this 知多少
    js数字进制转换
  • 原文地址:https://www.cnblogs.com/cainiaoxiaoxie/p/12622213.html
Copyright © 2011-2022 走看看