之前项目中整合 Swagger 都是直接通过依赖 springfox-swagger、springfox-swagger-ui 两个 jar 包来实现的,最近发现 springfox 3.0.0版本已经有了自己的 SpringBoot Starter,使用起来更契合 SpringBoot 项目,非常方便,推荐给大家!
#使用官方Starter
我们先使用官方Starter来整合Swagger看看是否够简单!
- 首先在
pom.xml中添加springfox官方Swagger依赖;
1 2 3 4 5 6
| <!--springfox swagger官方Starter--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency>
|
- 添加Swagger的Java配置,配置好Api信息和需要生成接口文档的类扫描路径即可;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| /** * Swagger2API文档的配置 */ @Configuration public class Swagger2Config { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.macro.mall.tiny.controller")) .paths(PathSelectors.any()) .build(); }
private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("SwaggerUI演示") .description("mall-tiny") .contact(new Contact("macro", null, null)) .version("1.0") .build(); } }
|

- 两步即可搞定SpringBoot集成Swagger,是不是很简单!
#与之前版本相比
之前我们使用的是springfox 2.9.2版本,接下来对比下3.0.0的SpringBoot Starter使用,看看有何不同!
- 旧版本需要依赖
springfox-swagger2和springfox-swagger-ui两个配置,新版本一个Starter就搞定了,而且之前的版本如果不使用新版本的swagger-models和swagger-annotations依赖,访问接口会出现NumberFormatException问题;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <dependencies> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <exclusions> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> </exclusion> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> </dependency> <!--解决Swagger 2.9.2版本NumberFormatException--> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.6.0</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> <version>1.6.0</version> </dependency> </dependencies>
|

- 比如说我们只想在
dev环境下启用Swagger文档,而在prod环境下不想启用,旧版本我们可以通过@Profile注解实现;
1 2 3 4 5 6
| @Configuration @EnableSwagger2 @Profile(value = {"dev"}) public class Swagger2Config { }
|
- 新版本我们在SpringBoot配置文件中进行配置即可,
springfox.documentation.enabled在application-dev.yml配置为true,在application-prod.yml中配置为false。
#整合Spring Security使用
我们经常会在项目中使用Spring Security实现登录认证,接下来我们来讲下如何使用Swagger整合Spring Security,实现访问需要登录认证的接口。
- 如何访问需要登录认证的接口?只需在访问接口时添加一个合法的
Authorization请求头即可,下面是Swagger相关配置;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| /** * Swagger2API文档的配置 */ @Configuration public class Swagger2Config { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.macro.mall.tiny.controller")) .paths(PathSelectors.any()) .build() //添加登录认证 .securitySchemes(securitySchemes()) .securityContexts(securityContexts()); }
private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("SwaggerUI演示") .description("mall-tiny") .contact(new Contact("macro", null, null)) .version("1.0") .build(); }
private List<SecurityScheme> securitySchemes() { //设置请求头信息 List<SecurityScheme> result = new ArrayList<>(); ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header"); result.add(apiKey); return result; }
private List<SecurityContext> securityContexts() { //设置需要登录认证的路径 List<SecurityContext> result = new ArrayList<>(); result.add(getContextByPath("/brand/.*")); return result; }
private SecurityContext getContextByPath(String pathRegex) { return SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex(pathRegex)) .build(); }
private List<SecurityReference> defaultAuth() { List<SecurityReference> result = new ArrayList<>(); AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; result.add(new SecurityReference("Authorization", authorizationScopes)); return result; } }
|
- 我们需要在Spring Security中配置好Swagger静态资源的无授权访问,比如首页访问路径
/swagger-ui/;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| /** * SpringSecurity的配置 * Created by macro on 2018/4/26. */ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UmsAdminService adminService; @Autowired private RestfulAccessDeniedHandler restfulAccessDeniedHandler; @Autowired private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.csrf()// 由于使用的是JWT,我们这里不需要csrf .disable() .sessionManagement()// 基于token,所以不需要session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers(HttpMethod.GET, // 允许对于网站静态资源的无授权访问 "/", "/swagger-ui/", "/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js", "/swagger-resources/**", "/v2/api-docs/**" ) .permitAll() .antMatchers("/admin/login")// 对登录注册要允许匿名访问 .permitAll() .antMatchers(HttpMethod.OPTIONS)//跨域请求会先进行一次options请求 .permitAll() .anyRequest()// 除上面外的所有请求全部需要鉴权认证 .authenticated(); // 省略若干配置...... } }
|
- 调用登录接口获取token,账号密码为
admin:123456;

- 点击
Authorize按钮后输入Authorization请求头,之后就可以访问需要登录认证的接口了。

Swagger官方Starter解决了之前整合Swagger的一系列问题,简化了SpringBoot整合Swagger的过程,使用起来更加方便了。同时对于一些复杂的配置使用基本没有变化,一些之前的使用方式依然可以使用!
#项目源码地址
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-swagger