单一的微服务集成swagger:

maven:

  <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>
package fwz.cpjiang.ums.utils;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.ArrayList;
import java.util.List; @Configuration
@EnableSwagger2
public class SwaggerConfig { @Bean
public Docket createRestApi(){
ParameterBuilder tokenPar = new ParameterBuilder(); List<Parameter> pars = new ArrayList<Parameter>();
tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
pars.add(tokenPar.build());
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build().globalOperationParameters(pars);
} private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("用户管理 API Doc")
.description("This is a restful api document of 用户管理.")
.version("1.0")
.build();
} }

此时swagger只是存在于单一的微服务,很不方便

gateway整合swagger:

所有的微服务均按上述配置swagger

然后在gateway微服务中,添加如下配置:

package fwz.cpjiang.gateway.utils;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder; @Configuration
public class SwaggerConfig { @Bean
public SecurityConfiguration securityConfiguration() {
return SecurityConfigurationBuilder.builder().build();
} @Bean
public UiConfiguration uiConfiguration() {
return UiConfigurationBuilder.builder().build();
} }
package fwz.cpjiang.gateway.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*; import java.util.List;
import java.util.Optional; @RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler { private final SecurityConfiguration securityConfiguration;
private final UiConfiguration uiConfiguration;
private final SwaggerResourcesProvider swaggerResources; @Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources, SecurityConfiguration securityConfiguration, UiConfiguration uiConfiguration) {
this.swaggerResources = swaggerResources;
this.securityConfiguration = securityConfiguration;
this.uiConfiguration = uiConfiguration;
} @GetMapping("/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()),
HttpStatus.OK));
} @GetMapping("/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
} @GetMapping
public Mono<ResponseEntity<List<SwaggerResource>>> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
} }
package fwz.cpjiang.gateway.utils;

import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
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; @Primary
@Component
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider { public static final String API_URI = "/v2/api-docs";
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties; @Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream()
.filter(routeDefinition -> routes.contains(routeDefinition.getId()))
.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources
.add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs()
.get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", API_URI)))));
return resources;
} private SwaggerResource swaggerResource(String name, String url) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setUrl(url);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}
package fwz.cpjiang.gateway.utils;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration; import java.util.List; @Configuration
@ConfigurationProperties(prefix = "system")
public class UrlConfig {
// 配置文件使用list接收
private List<String> whiteList; public List<String> getWhiteList() {
return whiteList;
}
public void setWhiteList(List<String> whiteList) {
this.whiteList = whiteList;
}
}

yml配置文件:

system:
whiteList:
- "/swagger-ui.html"
- "/swagger-resources/**"
- "/v2/api-docs"
- "/admin/login"
routes:
- id: hbistc-ums
uri: lb://hbistc-ums
predicates:
- Path=/ums/**
filters:
- StripPrefix=1
- id: hbistc-mall
uri: lb://hbistc-mall
predicates:
- Path=/mall/**
filters:
- StripPrefix=1
package fwz.cpjiang.gateway.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm; import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID; /**
* JWT工具类
*/
public class JwtUtils { //有效期为
public static final Long JWT_TTL = 3600000L;// 60 * 60 *1000 一个小时
//设置秘钥明文
public static final String JWT_KEY = "joijgisdlwejjjfeawoGdeizeffsaz"; /**
* 创建token
*
* @param id
* @param subject
* @param ttlMillis
* @return
*/
public static String createJWT(String id, String subject, Long ttlMillis) { SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
if (ttlMillis == null) {
ttlMillis = JwtUtils.JWT_TTL;
}
long expMillis = nowMillis + ttlMillis;
Date expDate = new Date(expMillis);
SecretKey secretKey = generalKey(); JwtBuilder builder = Jwts.builder()
.setId(id) //唯一的ID
.setSubject(subject) // 主题 可以是JSON数据
.setIssuer("admin") // 签发者
.setIssuedAt(now) // 签发时间
.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
.setExpiration(expDate);// 设置过期时间
return builder.compact();
} /**
* 生成加密后的秘钥 secretKey
*
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getDecoder().decode(JwtUtils.JWT_KEY);
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
} /**
* 解析
*
* @param jwt
* @return
* @throws Exception
*/
public static Claims parseJWT(String jwt) throws Exception {
SecretKey secretKey = generalKey();
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(jwt)
.getBody(); } public static void main(String[] args) throws Exception {
String token = createJWT(UUID.randomUUID().toString(), "ggggggg", null);
System.out.println(token);
Claims c = parseJWT(token);
String id = c.getId();
System.out.println(id);
}
}
package fwz.cpjiang.gateway.filter;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import fwz.cpjiang.gateway.utils.JwtUtils;
import fwz.cpjiang.gateway.utils.UrlConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufFlux; import java.util.HashMap;
import java.util.Map; /**
* 鉴权过滤器 验证token
*/ @Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
private static final String AUTHORIZE_TOKEN = "token";
@Autowired
private UrlConfig urlConfig;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1. 获取请求
ServerHttpRequest request = exchange.getRequest();
//2. 则获取响应
ServerHttpResponse response = exchange.getResponse();
//3. 如果是登录请求则放行
for (int i = 0; i <urlConfig.getWhiteList().size() ; i++) {
if (request.getURI().getPath().contains(urlConfig.getWhiteList().get(i))) {
return chain.filter(exchange);
}
} //4. 获取请求头
HttpHeaders headers = request.getHeaders();
//5. 请求头中获取令牌
String token = headers.getFirst(AUTHORIZE_TOKEN); //6. 判断请求头中是否有令牌
if (StrUtil.isEmpty(token)) {
//7. 响应中放入返回的状态吗, 没有权限访问
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//8. 返回
//return response.setComplete();
//设置响应头信息Content-Type类型
response.getHeaders().add("Content-Type","application/json");
//设置返回json数据
return response.writeAndFlushWith(Flux.just(ByteBufFlux.just(response.bufferFactory().wrap(getWrapData())))); } //9. 如果请求头中有令牌则解析令牌
try {
JwtUtils.parseJWT(token);
} catch (Exception e) {
e.printStackTrace();
//10. 解析jwt令牌出错, 说明令牌过期或者伪造等不合法情况出现
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//11. 返回
//设置响应头信息Content-Type类型
response.getHeaders().add("Content-Type","application/json");
//设置返回json数据
return response.writeAndFlushWith(Flux.just(ByteBufFlux.just(response.bufferFactory().wrap(getWrapData())))); }
//12. 放行
return chain.filter(exchange);
} @Override
public int getOrder() {
return 0;
} private byte[] getWrapData() {
Map<String,String> map = new HashMap<>();
map.put("code","1");
map.put("msg","token is empty or illegal");
try {
return new ObjectMapper().writeValueAsString(map).getBytes();
} catch (JsonProcessingException e) {
//
}
return "".getBytes();
}
}

进行白名单过滤

然后访问网关:

可以发现红框内出现了微服务切换的选项,至此整合完毕

springcloud+gateway微服务整合swagger的更多相关文章

  1. SpringCloud Gateway微服务网关实战与源码分析-上

    概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...

  2. 用SpringCloud进行微服务架构演进

    在<架构师必须要知道的阿里的中台战略与微服务> 中已经阐明选择SpringCloud进行微服务架构实现中台战略,因此下面介绍SpringCloud的一些内容,SpringCloud已经出来 ...

  3. SpringCloud学习--微服务架构

    目录 微服务架构快速指南 SOA Dubbo Spring Cloud Dubbo与SpringCloud对比 微服务(Microservice)架构快速指南 什么是软件架构? 软件架构是一个包含各种 ...

  4. springCloud搭建微服务集群+Zuul服务器端负载均衡

    概述 最近研究了一下springCloud的微服务集群,主要用到了SpringCloud的服务发现和服务器端负载均衡,所有的项目都是用的springboot,可以和springCloud无缝对接. 技 ...

  5. SpringCloud与微服务Ⅲ --- SpringCloud入门概述

    一. 什么是SpringCloud SpringCloud基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了基于NetF ...

  6. 一个C#开发者学习SpringCloud搭建微服务的心路历程

    前言 Spring Cloud很火,很多文章都有介绍如何使用,但对于我这种初学者,我需要从创建项目开始学起,所以这些文章对于我的启蒙,帮助不大,所以只好自己写一篇文章,用于备忘. SpringClou ...

  7. 基于Spring-Cloud的微服务框架设计

    基于Spring-Cloud的微服务框架设计 先进行大的整体的框架整理,然后在针对每一项进行具体的详细介绍

  8. SpringCloud与微服务系列专栏

    一. 前置知识 学习SpringCloud之前需要具备和掌握如下框架和工具的使用:SpringMVC,Spring,Spring Boot,Mybatis,Maven,Git. SpringCloud ...

  9. springCloud进阶(微服务架构&Eureka)

    springCloud进阶(微服务架构&Eureka) 1. 微服务集群 1.1 为什么要集群 为了提供并发量,有时同一个服务提供者可以部署多个(商品服务).这个客户端在调用时要根据一定的负责 ...

随机推荐

  1. SQLAlchemy(十)

    ORM操作在实际项目中的应用非常多,涉及到的框架也是根据不同的项目有不同的处理模块,不过操作流程和步骤都是大同小异基本没有什么太大变化,唯一需要注意的就是在实际操作过程中你要使用的ORM框架的处理性能 ...

  2. PowerShell 管道符之Select的使用方法【一】

    之前我文章中我们略微提到过管道符的操作,但并不多,这篇主要讲解一下详细的使用方法 假设我们要对数组中的数字1-10中我想要从右往左换句话说就是从字符串最后一个字开始倒过来往前数截取6个子字符串时可以这 ...

  3. SQL高级优化(五)之执行计划

    一.explain 执行计划:在MySQL中可以通过explain关键字模拟优化器执行SQL语句,从而知道MySQL是如何处理SQL语句的. explain:MySQL执行计划的工具,查看MySQL如 ...

  4. Elasticsearch安装与配置

    一.下载(华为云) https://mirrors.huaweicloud.com/elasticsearch/https://mirrors.huaweicloud.com/kibana/7.6.2 ...

  5. vue 快速入门 系列 —— 模板

    其他章节请看: vue 快速入门 系列 模板 前面提到 vue 中的虚拟 dom 主要做两件事: 提供与真实节点对应的 vNode 新旧 vNode 对比,寻找差异,然后更新视图 ①.vNode 从何 ...

  6. WebRTC本地选择codec(web本地模拟)

    视频编码后,再进行发送.WebRTC建立视频连接前,可以选择codec.一般来说支持多种codec,以VP8和H264为代表. Codec: 编码译码器,编解码器 示例代码 写一个示例,用户可以在发送 ...

  7. 解决excel两表之间数据关联关系,知道这几招就够了

    用过SAP的凭证批量录入模板(Excel文件)的都知道,一个凭证由[抬头]和多个[行项目]组成,这是一个关于excel两表信息关联的典型场景. 这里头蕴藏着一个麻烦:当我们需要一次性录入多个凭证时,如 ...

  8. VUE3 之 全局组件与局部组件

    1. 概述 老话说的好:忍耐是一种策略,同时也是一种性格磨炼. 言归正传,今天我们来聊聊 VUE 的全局组件与局部组件. 2. 全局组件 2.1 不使用组件的写法  <body> < ...

  9. Go 常用函数

    #### Go 常用函数,错误处理这一节我们来学习一下Go 常用的函数,这些函数有些是内置的,有些是官方标准库内的, 熟悉这些函数对程序开发来讲还是很重要的; 1. len("abc&quo ...

  10. 理解cpu load

    三种命令 1. w 2. uptime 3. top CPU负载和CPU利用率的区别 1)CPU利用率:显示的是程序在运行期间实时占用的CPU百分比 2)CPU负载:显示的是一段时间内正在使用和等待使 ...