Zuul Swagger 整合

懵懂的女人 提交于 2020-01-13 06:26:27

疯狂创客圈 Java 高并发【 亿级流量聊天室实战】实战系列 【博客园总入口

架构师成长+面试必备之 高并发基础书籍 【Netty Zookeeper Redis 高并发实战


前言

Crazy-SpringCloud 微服务脚手架 &视频介绍

Crazy-SpringCloud 微服务脚手架,是为 Java 微服务开发 入门者 准备的 学习和开发脚手架。并配有一系列的使用教程和视频,大致如下:

高并发 环境搭建 图文教程和演示视频,陆续上线:

中间件 链接地址
Linux Redis 安装(带视频) Linux Redis 安装(带视频)
Linux Zookeeper 安装(带视频) Linux Zookeeper 安装, 带视频
Windows Redis 安装(带视频) Windows Redis 安装(带视频)
RabbitMQ 离线安装(带视频) RabbitMQ 离线安装(带视频)
ElasticSearch 安装, 带视频 ElasticSearch 安装, 带视频
Nacos 安装(带视频) Nacos 安装(带视频)

Crazy-SpringCloud 微服务脚手架 图文教程和演示视频,陆续上线:

组件 链接地址
Eureka Eureka 入门,带视频
SpringCloud Config springcloud Config 入门,带视频
spring security spring security 原理+实战
Spring Session SpringSession 独立使用
分布式 session 基础 RedisSession (自定义)
重点: springcloud 开发脚手架 springcloud 开发脚手架
SpingSecurity + SpringSession 死磕 (写作中) SpingSecurity + SpringSession 死磕

小视频以及所需工具的百度网盘链接,请参见 疯狂创客圈 高并发社群 博客

Zuul Swagger整合的场景

我们知道,Swagger2整合到项目中,可以非常方便地进行接口测试,是前后端对接效率提高。

现在,我们可以在Zuul中整合Swagger2,通过Zuul配置文件配置的映射路径,来生成整体的微服务服务接口的统一测试的 Dashboard。

step1: Zuul引入swagger2的依赖:

在cloud-zuul子模块的pom.xml文件中引入swagger2的两个Maven依赖:

 <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>${swagger.version}</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>${swagger.version}</version>
    </dependency>

step2: Zuul的Swagger2配置类

需要2个比较重要的配置类:

(1)是SwaggerConfig 类,主要用于配置Swagger描述信息;

(2)是DocumentationConfig 类,主要用于整合其他服务的接口API。

一: SwaggerConfig 类

SwaggerConfig 配置类的代码,大致如下:

package com.crazymaker.springcloud.cloud.center.zuul.config;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket buildDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(buildApiInf()) // .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage(""))// 需要生成文档的包的位置
                .paths(PathSelectors.any())
                .build();
    }
    //api的描述信息构建
    private ApiInfo buildApiInf() {
        return new ApiInfoBuilder()
                .title("疯狂创客圈springcloud 高并发实战")
                .description("Zuul+Swagger2构建RESTful APIs")
                .termsOfServiceUrl("https://www.cnblogs.com/crazymakercircle/")
       .contact(new Contact("疯狂创客圈", "https://www.cnblogs.com/crazymakercircle/", ""))
                .version("1.0")
                .build();
    }
}

二:DocumentationConfig 类

主要用于整合其他服务的接口API,代码大致如下:

package com.crazymaker.springcloud.cloud.center.zuul.config;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

@Component
@Primary
public class DocumentationConfig implements SwaggerResourcesProvider {
    private final RouteLocator routeLocator;

    public DocumentationConfig(RouteLocator routeLocator) {
        this.routeLocator = routeLocator;
    }

    /**
     * 配置所有的微服务
     *
     * @return
     */
/*    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<Route> routes = routeLocator.getRoutes();
        routes.forEach(route -> {
            resources.add(swaggerResource(route.getId(), route.getFullPath().replace("**", "v2/api-docs"), "1.0"));
        });
        return resources;
    }*/

    /**
     * 配置特定的微服务
     * @return
     */
    @Override
    public List<SwaggerResource> get() {
        List resources = new ArrayList<>();
        resources.add(swaggerResource("秒杀", "/seckill-provider/v2/api-docs", "1.0"));
        resources.add(swaggerResource("消息", "/message-provider/v2/api-docs", "1.0"));
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location, String version) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(version);
        return swaggerResource;
    }
}

SwaggerResourcesProvider 是资源提供者,我们重写他,把各个微服务的API文档资源路径返回。

既可以 配置所有的微服务,也可以配置特定的微服务。

如果 配置所有的微服务(注释部分),可以通过遍历eureka路由方式自动添加所有微服务 API 文档。

step3:微服务的Swagger2配置类

微服务提供者,也需要引入Swagger2依赖包,并且进行Swagger2的配置,代码如下:

package com.crazymaker.springcloud.user.info.config;

import com.google.common.collect.Lists;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * swagger配置
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket templateApi() {
        ParameterBuilder tokenPar = new ParameterBuilder();
        tokenPar.name("token").description("token令牌")
                .modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .useDefaultResponseMessages(false)
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                .build().globalOperationParameters(Lists.newArrayList(tokenPar.build()));
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("springcloud 高并发 实战 Rest API 文档")
                .version("1.0")
                .build();
    }
}

step4:配置 SpringSecurity

如果加了SpringSecurity 进行权限控制,需要给 swagger 的连接,加上全部的许可,不进行拦截。

@EnableWebSecurity()
public class UserWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserAuthService userAuthService;


    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers(
                        "/v2/api-docs",
                        "/swagger-resources/configuration/ui",
                        "/swagger-resources",
                        "/swagger-resources/configuration/security",
                        "/swagger-ui.html",
                        "/api/user/login/v1",
//                        "/api/user/add/v1",
//                        "/api/user/speed/test/v1",
//                        "/api/user/say/hello/v1",
//                        "/api/user/*/detail/v1",
                        "/api/crazymaker/duty/info/user/login")
                .permitAll()
                .anyRequest().authenticated()

//                .antMatchers("/image/**").permitAll()
//                .antMatchers("/admin/**").hasAnyRole("ADMIN")
                .and()

                .formLogin().disable()
                .sessionManagement().disable()
                .cors()
                .and()

                .addFilterAfter(new OptionsRequestFilter(), CorsFilter.class)
                .apply(new JsonLoginConfigurer<>()).loginSuccessHandler(jsonLoginSuccessHandler())
                .and()
                .apply(new JwtAuthConfigurer<>()).tokenValidSuccessHandler(jwtRefreshSuccessHandler()).permissiveRequestUrls("/logout")
                .and()
                .logout()
//              .logoutUrl("/logout")   //默认就是"/logout"
                .addLogoutHandler(tokenClearLogoutHandler())
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
                .and()
                .addFilterBefore(springSessionRepositoryFilter(), SessionManagementFilter.class)
                .sessionManagement().disable()
        ;


    }


    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/api/user/login/v1",
                "/v2/api-docs",
                "/swagger-resources/configuration/ui",
                "/swagger-resources",
                "/swagger-resources/configuration/security",
//                "/api/user/say/hello/v1",
//                "/api/user/add/v1",
//                "/api/user/speed/test/v1",
//                "/api/user/*/detail/v1",
                "/images/**",
                "/swagger-ui.html",
                "/webjars/**",
                "**/favicon.ico",
                "/css/**",
                "/js/**",
                "/api/crazymaker/info/user/login"
        );

    }
///....
}

生产环境上,需要在 反向代理Nginx上,将swagger的路径,进行拒绝

API整合之结果查看

运行相关服务和zuul-swagger网关,输入:http://192.168.233.1:7799/swagger-ui.html

img

具体,请关注 Java 高并发研习社群博客园 总入口


最后,介绍一下疯狂创客圈:疯狂创客圈,一个Java 高并发研习社群博客园 总入口

疯狂创客圈,倾力推出:面试必备 + 面试必备 + 面试必备 的基础原理+实战 书籍 《Netty Zookeeper Redis 高并发实战

img


疯狂创客圈 Java 死磕系列

  • Java (Netty) 聊天程序【 亿级流量】实战 开源项目实战

  • Netty 源码、原理、JAVA NIO 原理
  • Java 面试题 一网打尽

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!