Swagger的使用

it2023-05-30  71

Swagger

Swagger官网


导语:

相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前端调用后端,还是后端调用后端,都期望有一个好的接口文档。但是这个接口文档对于程序员来说,就跟注释一样,经常会抱怨别人写的代码没有写注释,然而自己写起代码起来,最讨厌的,也是写注释。所以仅仅只通过强制来规范大家是不够的,随着时间推移,版本迭代,接口文档往往很容易就跟不上代码,等等等的问题。


为了解决以上API接口问题,就出现了Swagger!说白了就是为了解决前后端分离开发带来的对接问题

Swagger是什么?

Swagger是一款让你更好地书写API文档的框架。

Swagger是一个功能强大且易于使用的API开发人员工具套件,适用于团队和个人,可在整个API生命周期(从设计和文档到测试和部署)中进行开发。


Swagger怎么用?

本文使用的是Springboot构建项目!项目使用Swagger2!

Swagger需要的组件

Swagger需要使用到Springfox

Swagger2ui

先看看Swagger-ui界面

创建springboot项目

创建的是web项目,这里不讲如何创建。

到Maven查找组件

Maven官网

把依赖导入pom文件

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> 编写一个HelloController工程 import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello.do") public String hello(){ return "hello swagger"; } }

启动Springboot,访问controller,没有出错就继续往下走。

编写Swagger配置类 import org.springframework.context.annotation.Configuration; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration // 定义为配置类 @EnableSwagger2 // 开启Swagger2 public class SwaggerConfig { } 访问

看看我们导入的依赖,可以找到一个swagger-ui.html页面

访问http://localhost:8080/swagger-ui.html

第一个简单的swagger页面就弄好了!


配置Swagger

Swagger的bean实例 Docket

@Configuration // 定义为配置类 @EnableSwagger2 // 开启Swagger2 public class SwaggerConfig { // 配置Swagger的Docket的bean实例 @Bean public Docket docket(){ return new Docket(DocumentationType.SWAGGER_2); } }

点进Docket构造器里面,ApiInfo使用默认的配置,此时我们可以为ApiInfo设值

public Docket(DocumentationType documentationType) { this.apiInfo = ApiInfo.DEFAULT; //api信息 this.groupName = "default"; this.enabled = true; this.genericsNamingStrategy = new DefaultGenericTypeNamingStrategy(); this.applyDefaultResponseMessages = true; this.host = ""; this.pathMapping = Optional.absent(); this.apiSelector = ApiSelector.DEFAULT; this.enableUrlTemplating = false; this.vendorExtensions = Lists.newArrayList(); this.documentationType = documentationType; }

点进ApiInfo类中,查看默认配置DEFAULT

static { DEFAULT = new ApiInfo("Api Documentation", "Api Documentation", "1.0", "urn:tos", DEFAULT_CONTACT, "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList()); }

自定义ApiInfo信息

@Configuration // 定义为配置类 @EnableSwagger2 // 开启Swagger2 public class SwaggerConfig { // 配置Swagger的Docket的bean实例 @Bean public Docket docket() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()); } // 配置swagger的ApiInfo信息 public ApiInfo apiInfo() { // 作者信息 Contact contact = new Contact("hao","https://blog.csdn.net/weixin_44151739/article/details/109183587","xxx@qq.com"); return new ApiInfo( "hao的Swagger API文档", "今天怎么过,明天就怎么过!", "V1.0", "https://blog.csdn.net/weixin_44151739/article/details/109183587", contact, "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList() ); } }

启动服务器访问


配置扫描接口及配置

默认的不管,我们看自定义的controller,存在多种方式访问,因为我们代码中使用的是@RequestMapping("/hello.do"),没有设置具体访问方式

接下来我们讲Swagger如何扫描到我们controller的

Docket的select()方法

指定扫描包 // 配置Swagger的Docket的bean实例 @Bean public Docket docket() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() // RequestHandlerSelectors 配置要扫描接口的方式 // basePackage 指定要扫描的包 .apis(RequestHandlerSelectors.basePackage("com.hao.swagger.controller")) .build(); }

重启服务器,访问,你会发现默认的那个不见了,只剩下我们指定包中的controller

点进RequestHandlerSelectors类中,具体内容省略,查看一下扫描方法

public class RequestHandlerSelectors { // 扫描所有 public static Predicate<RequestHandler> any() { } // 不扫描 public static Predicate<RequestHandler> none() { } // 通过方法的注解去扫描 public static Predicate<RequestHandler> withMethodAnnotation(final Class<? extends Annotation> annotation) { } // 通过类的注解去扫描 public static Predicate<RequestHandler> withClassAnnotation(final Class<? extends Annotation> annotation) { } private static Function<Class<?>, Boolean> annotationPresent(final Class<? extends Annotation> annotation) { } private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) { } // 扫描指定包 public static Predicate<RequestHandler> basePackage(final String basePackage) { } private static Optional<? extends Class<?>> declaringClass(RequestHandler input) { } } 过滤指定路径 // 配置Swagger的Docket的bean实例 @Bean public Docket docket() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() // RequestHandlerSelectors 配置要扫描接口的方式 // basePackage 指定要扫描的包 .apis(RequestHandlerSelectors.basePackage("com.hao.swagger.controller")) // paths 过滤路径 // ant 过滤指定名称 .paths(PathSelectors.ant("/hao/**")) .build(); }

重启服务器,访问,没有接口了,我们自定义就一个接口,路径为/hello.do,此时要扫描的是/hao开头的

点进PathSelectors类中,具体内容省略,查看一下过滤方法

public class PathSelectors { // 过滤全部 public static Predicate<String> any() { } // 不过滤 public static Predicate<String> none() { } // 正则 public static Predicate<String> regex(final String pathRegex) { } // 指定过滤 public static Predicate<String> ant(final String antPattern) { } } 配置是否启动Swagger // 配置Swagger的Docket的bean实例 @Bean public Docket docket() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) // 是否开启Swagger,默认为true(开启),现在设置为false .enable(false) .select() // RequestHandlerSelectors 配置要扫描接口的方式 // basePackage 指定要扫描的包 .apis(RequestHandlerSelectors.basePackage("com.hao.swagger.controller")) // paths 过滤路径 // ant 过滤指定名称 .paths(PathSelectors.ant("/hao/**")) .build(); }

重启服务器,访问,Swagger被禁用


案例

我只希望Swagger在生产环境中使用,在发布的时候不使用

修改enable的参数

创建两个配置类

application-dev.properties:开发环境

application-pro.properties:上线环境

#application.properties spring.profiles.active=dev #application-dev.properties server.port=8081 #application-pro.properties server.port=8082

这里我们使用dev(开发)环境,如何修改controller类的docket方法,注意修改enable的变量

// 配置Swagger的Docket的bean实例 @Bean public Docket docket(Environment environment) { // 设置要显式的Swagger环境,of为可变参数 Profiles profiles = Profiles.of("dev", "test"); // 通过environment.acceptsProfiles判断是否处在自己设定的环境当中 boolean b = environment.acceptsProfiles(profiles); return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) // 这里使用变量b .enable(b) .select() .apis(RequestHandlerSelectors.basePackage("com.hao.swagger.controller")) .paths(PathSelectors.ant("/hao/**")) .build(); }

重启服务器,访问的端口为8081,记得修改端口

然后我们再测试一下上线版

#application.properties spring.profiles.active=pro

重启服务器,访问的端口为8082,记得修改端口


配置API文档的分组

在之前写的代码中为组设置名称

@Bean public Docket docket(Environment environment) { Profiles profiles = Profiles.of("dev", "test"); boolean b = environment.acceptsProfiles(profiles); return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) // 为分组设置名称 .groupName("hao") .enable(b) .select() .apis(RequestHandlerSelectors.basePackage("com.hao.swagger.controller")) .paths(PathSelectors.ant("/hao/**")) .build(); }

把环境设置回dev,然后访问,记得端口是8081

#application.properties spring.profiles.active=dev

可以看到当前的组名被改为hao


可以理解为,一个Docket对象就是一个组

讲分组之前,我们需要清空之前SwaggerConfig配置类中配置的代码

环境也不需要设置了,清空就好(application.properties配置文件的内容清掉)

编写3个Docket对象

@Configuration // 定义为配置类 @EnableSwagger2 // 开启Swagger2 public class SwaggerConfig { @Bean public Docket docket1(){ return new Docket(DocumentationType.SWAGGER_2).groupName("A"); } @Bean public Docket docket2(){ return new Docket(DocumentationType.SWAGGER_2).groupName("B"); } @Bean public Docket docket3(){ return new Docket(DocumentationType.SWAGGER_2).groupName("C"); } } 访问服务器,记得端口改回8080,此时就可以看到有3个分组了

每个开发者有自己的Docket对象(自己的组),独立开发,最终把模块合并在一起,也能明显知道谁开发的功能。


实体类配置

添加一个实体类User public class User { private String name; private Integer age; public String getName() { return name; } public Integer getAge() { return age; } } 修改controller @RestController public class HelloController { @GetMapping("/hello.do") public String hello(){ return "hello swagger"; } // 只要我们的接口中,返回值中存在实体类,他就会被扫描到Swagger中 @GetMapping("/user.do") public User user(){ return new User(); } } 启动服务器,访问


给实体类起名字

实体类用上以下注解

@ApiModel(“用户实体类”)

@ApiModelProperty(“用户名”)

@ApiModelProperty(“年龄”)

@ApiModel("用户实体类") public class User { @ApiModelProperty("用户名") private String name; @ApiModelProperty("年龄") private Integer age; public String getName() { return name; } public Integer getAge() { return age; } }

给controller起名字

@ApiOperation(“Hello控制类”)

@ApiParam(“名字”)

@RestController public class HelloController { @ApiOperation("Hello控制类") @GetMapping("/hello.do") public String hello(@ApiParam("名字") String name){ return "hello swagger"; } // 只要我们的接口中,返回值中存在实体类,他就会被扫描到Swagger中 @GetMapping("/user.do") public User user(){ return new User(); } }


测试功能

@ApiOperation("Hello控制类") @GetMapping("/hello.do") public String hello(@ApiParam("名字") String name){ return "hello swagger"; }

点击Trt it out,因为需要参数,所以可以输入参数

按Execute提交请求,下面就可以观察请求后返回的结果

这里我们演示无参那个请求

因为返回User对象的属性没有设值,所以为null

可以的话,给个三连,谢谢!

最新回复(0)