乐趣区

关于java:还在手动整合SwaggerSwagger官方Starter是真的香

之前我的项目中整合 Swagger 都是间接通过依赖 springfox-swaggerspringfox-swagger-ui 两个 jar 包来实现的,最近发现 springfox 3.0.0 版本曾经有了本人的 SpringBoot Starter,应用起来更符合 SpringBoot 我的项目,十分不便,举荐给大家!

SpringBoot 实战电商我的项目 mall(40k+star)地址:https://github.com/macrozheng/mall

应用官网 Starter

咱们先应用官网 Starter 来整合 Swagger 看看是否够简略!

  • 首先在 pom.xml 中增加 springfox 官网 Swagger 依赖;
<!--springfox swagger 官网 Starter-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
  • 增加 Swagger 的 Java 配置,配置好 Api 信息和须要生成接口文档的类扫描门路即可;
/**
 * 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();}
}
  • 拜访 API 文档信息,拜访地址:http://localhost:8088/swagger-ui/

  • 两步即可搞定 SpringBoot 集成 Swagger,是不是很简略!

与之前版本相比

之前咱们应用的是 springfox 2.9.2 版本,接下来比照下 3.0.0 的 SpringBoot Starter 应用,看看有何不同!

  • 旧版本须要依赖 springfox-swagger2springfox-swagger-ui两个配置,新版本一个 Starter 就搞定了,而且之前的版本如果不应用新版本的 swagger-modelsswagger-annotations依赖,拜访接口会呈现 NumberFormatException 问题;
<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>
  • 新版本去除了一些第三方依赖,包含 guava,之前应用旧版本时就因为guava 版本问题导致过依赖抵触,具体能够看下《给 Swagger 降级了新版本,没想到竟然有这么多坑!》;
  • 新版本和旧版本文档拜访门路产生了变动,新版本为:http://localhost:8088/swagger-ui/,旧版本为:http://localhost:8088/swagger-ui.html
  • 新版本中新增了一些 SpringBoot 配置,springfox.documentation.enabled配置能够管制是否启用 Swagger 文档生成性能;

  • 比如说咱们只想在 dev 环境下启用 Swagger 文档,而在 prod 环境下不想启用,旧版本咱们能够通过 @Profile 注解实现;
@Configuration
@EnableSwagger2
@Profile(value = {"dev"})
public class Swagger2Config {}
  • 新版本咱们在 SpringBoot 配置文件中进行配置即可,springfox.documentation.enabledapplication-dev.yml 配置为 true,在 application-prod.yml 中配置为 false。

整合 Spring Security 应用

咱们常常会在我的项目中应用 Spring Security 实现登录认证,接下来咱们来讲下如何应用 Swagger 整合 Spring Security,实现拜访须要登录认证的接口。

  • 如何拜访须要登录认证的接口?只需在拜访接口时增加一个非法的 Authorization 申请头即可,上面是 Swagger 相干配置;
/**
 * 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/
/**
 * 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…

本文 GitHub https://github.com/macrozheng/mall-learning 曾经收录,欢送大家 Star!

退出移动版