knife4j是swagger的增强版,更契合微服务架构,ui前身是swagger-bootstrap-ui,api注解的使用方式和swagger一致。
 

springboot整合knife4j

依赖

<!-- 包含了ui界面 -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <!-- 2.x基于springfox2.x,3.x基于springfox3.x-->
    <version>3.0.2</version>
</dependency>

 
配置类

@Configuration
@EnableSwagger2  //2.x用 @EnableSwagger2WebMvc
public class Knife4jConfig {

    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("xm商城接口文档")
                .description("xm商城1.0的接口文档,仅限内部使用")
                .termsOfServiceUrl("http://www.xmmall.com")
                .contact(new Contact("chy", "www.chy.com", "xxxxxxx@qq.com"))
                .version("1.0")
                .build();
    }

    @Bean
    public Docket defaultApi2() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                //分组名称
                //.groupName("1.0版本")
                .select()
                //指定controller(接口)扫描的包路径
                .apis(RequestHandlerSelectors.basePackage("com.chy.mall.orderserver.controller"))
                .paths(PathSelectors.any())
                .build();
    }

}

和swagger-bootstrap-ui的访问地址一致,都是 doc.html 。

如果使用JRebel启动,会报一些错,这是jrebel、knife4j之间的兼容问题,影响不大

JRebel: ERROR Class ‘springfox.documentation.schema.CachingModelDependencyProvider’ could not be processed by org.zeroturnaround.jrebel.springfox.cbp.CachingModelDependencyProviderCBP@sun.misc.Launcher$AppClassLoader@18b4aac2: org.zeroturnaround.bundled.javassist.CannotCompileException: [source error] asMap() not found in java.util.Map

这种方式常用来写单个服务的接口文档,同事使用时逐个找接口文档不方便,所以在微服务项目中,还需要在网关处聚合各个接口文档,提供一个统一的接口文档访问入口。

 

springcloud zuul聚合接口文档

依赖

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-micro-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>

 
配置类

@Component
@Primary
public class SwaggerResourceConfig implements SwaggerResourcesProvider {

    @Autowired
    private RouteLocator routeLocator;

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        //这个配置影响不大
        swaggerResource.setSwaggerVersion("3.0");
        return swaggerResource;
    }

    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resourceList = new ArrayList<>();
        //获取所有router
        List<Route> routeList = routeLocator.getRoutes();
        for (Route route:routeList) {
            //排除不需要参与文档聚合的服务
            if (!route.getId().equals("monitor-server")){
                //第一个参数指定服务名,id是服务名 eg. order-server
                //第二个参数指定该服务的文档访问接口 eg. /order-server/v2/api-docs。fullPath是该服务的路由地址 eg. /order-server/**
                resourceList.add(swaggerResource(route.getId(), route.getFullPath().replace("/**", "/v2/api-docs")));
            }
        }
        return resourceList;
    }

}

/v2/api-docs

  • v2是该服务文档配置类上的@EnableSwagger2的2,跟配置类、pom.xml中的swagger版本无关
  • api-docs是固定的,不要在服务的接口文档配置类中配置groupName,因为本来是api-docs?groupName=xxx,配置groupName后不好维护网关中配置的地址。

各个服务的接口文档可以是knife4j,也可以是swagger。

访问地址是网关下的doc.html,如果一个SwaggerResource都没有,访问时js会提示空指针。