事情是这样的,前两天同事跟我们分享了一下他在学习SpringBoot的时候,用了Swagger2,生成的接口文档美如画,我甚是心动,于是乎,我也捣鼓了一下,感觉一下子就起飞了。话不多说,开搞~
添加依赖
在SpringBoot项目中加入两个Swagger2相关的依赖,前提是需要加入spring-boot-starter-web依赖,如下:
<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>
Swagger2 配置
@Configuration@EnableSwagger2public class SwaggerConfig { @Bean public Docket swaggerSpringMvcPlugin() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)).paths(PathSelectors.any()).build() } // 构建 api文档的详细信息函数 private ApiInfo apiInfo() { Contact contact = new Contact("我的团队", "www.my.com", "my@my.com"); return new ApiInfoBuilder().title("RESTful API") // 页面标题 .description("这里是api的描述内容") // 描述 .contact(contact) // 创建人 .version("1.0.1") // 版本号 .build(); }}
非常简单的配置,此时启动项目,输入 http://localhost:8080/swagger-ui.html
,能够看到如下页面,说明已经配置成功了:
配置接口
@RestController@RequestMapping("user")@Api(tags = "用户管理相关接口")public class UserController { @Autowired private UserService userService; @GetMapping("/getUserById") @ApiOperation("获取单个用户的接口") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户id", defaultValue = "2", required = true) }) public User getUserById(Integer id) { return this.userService.getUserById(id); } @GetMapping("/getUserList") @ApiOperation("获取全部用户的接口") public List<User> getUserList() { return this.userService.getUserList(); }}
这里边涉及到多个 API,分别说明一下:
- @Api 注解可以用来标记当前 Controller 的功能。
- @ApiOperation 注解用来标记一个方法的作用。
- @ApiImplicitParam 注解用来描述一个参数,可以配置参数的中文含义,也可以给参数设置默认值,这样在接口测试的时候可以避免手动输入。
- 如果有多个参数,则需要使用多个 @ApiImplicitParam 注解来描述,多个 @ApiImplicitParam 注解需要放在一个 @ApiImplicitParams 注解中。
至此,整合Swagger2就算完成了,但是,你以为这样就完了吗?
如果项目整合了JWT,那么在测试接口的时候就需要填写token,那么如何在Swagger2的配置里实现呢,请往下面看~
全局配置
@Configuration@EnableSwagger2public class SwaggerConfig { @Bean public Docket swaggerSpringMvcPlugin() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)).paths(PathSelectors.any()).build() .securitySchemes(securitySchemes()).securityContexts(securityContexts()); } private List<ApiKey> securitySchemes() { List<ApiKey> apiKeyList = new ArrayList<ApiKey>(); apiKeyList.add(new ApiKey("token", "token", "header")); return apiKeyList; } private List<SecurityContext> securityContexts() { List<SecurityContext> securityContexts = new ArrayList<>(); securityContexts.add(SecurityContext.builder().securityReferences(defaultAuth()) .forPaths(PathSelectors.regex("^(?!auth).*$")).build()); return securityContexts; } List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; List<SecurityReference> securityReferences = new ArrayList<>(); securityReferences.add(new SecurityReference("token", authorizationScopes));//有许多教程说明中这个地方是Authorization,导致不能带入全局token,因为securitySchemes()方法中header写入token,所以这个地方改为token就可以了 return securityReferences; } // 构建 api文档的详细信息函数 private ApiInfo apiInfo() { Contact contact = new Contact("我的团队", "www.my.com", "my@my.com"); return new ApiInfoBuilder().title("RESTful API") // 页面标题 .description("这里是api的描述内容") // 描述 .contact(contact) // 创建人 .version("1.0.1") // 版本号 .build(); }}
在Authorize中填写token即可在每次请求时,在header中带上token。
每个接口单独配置token
@Configuration@EnableSwagger2public class SwaggerConfig { @Bean public Docket swaggerSpringMvcPlugin() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)).paths(PathSelectors.any()).build() .globalOperationParameters(setHeaderToken()); } private List<Parameter> setHeaderToken() { ParameterBuilder tokenPar = new ParameterBuilder(); List<Parameter> pars = new ArrayList<>(); tokenPar.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); pars.add(tokenPar.build()); return pars; } // 构建 api文档的详细信息函数 private ApiInfo apiInfo() { Contact contact = new Contact("我的团队", "www.my.com", "my@my.com"); return new ApiInfoBuilder().title("RESTful API") // 页面标题 .description("这里是api的描述内容") // 描述 .contact(contact) // 创建人 .version("1.0.1") // 版本号 .build(); }}
如图,在每个api的参数里需要单独填写token。
小结,通过以上配置,即可轻松愉快地整合Swagger2,下班了,开溜。