网关项目的Knife4j配置+网关的冲突问题及解决

我们希望配置网关后能够进行Knife4j测试,

这样就可以不用切来切去了,

我们就需要进行Knife4j配置实现

此配置是固定的

当微服务项目时网关项目配置各子模块的Knife4j功能,就可以直接复制这几个类即可:

config\controller\filter

config包:

        SwaggerProvider类 

@Component
public class SwaggerProvider implements SwaggerResourcesProvider {
    /**
     * 接口地址
     */
    public static final String API_URI = "/v2/api-docs";
    /**
     * 路由加载器
     */
    @Autowired
    private RouteLocator routeLocator;
    /**
     * 网关应用名称
     */
    @Value("${spring.application.name}")
    private String applicationName;

    @Override
    public List get() {
        //接口资源列表
        List resources = new ArrayList<>();
        //服务名称列表
        List routeHosts = new ArrayList<>();
        // 获取所有可用的应用名称
        routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null)
                .filter(route -> !applicationName.equals(route.getUri().getHost()))
                .subscribe(route -> routeHosts.add(route.getUri().getHost()));
        // 去重,多负载服务只添加一次
        Set existsServer = new HashSet<>();
        routeHosts.forEach(host -> {
            // 拼接url
            String url = "/" + host + API_URI;
            //不存在则添加
            if (!existsServer.contains(url)) {
                existsServer.add(url);
                SwaggerResource swaggerResource = new SwaggerResource();
                swaggerResource.setUrl(url);
                swaggerResource.setName(host);
                resources.add(swaggerResource);
            }
        });
        return resources;
    }
}

controller包:

        SwaggerController类

@RestController
@RequestMapping("/swagger-resources")
public class SwaggerController {
    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;
    @Autowired(required = false)
    private UiConfiguration uiConfiguration;
    private final SwaggerResourcesProvider swaggerResources;
    @Autowired
    public SwaggerController(SwaggerResourcesProvider swaggerResources) {
        this.swaggerResources = swaggerResources;
    }
    @GetMapping("/configuration/security")
    public Mono> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }
    @GetMapping("/configuration/ui")
    public Mono> uiConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
    }
    @GetMapping("")
    public Mono swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}

 filter包:

        SwaggerHeaderFilter类

@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
    private static final String HEADER_NAME = "X-Forwarded-Prefix";

    private static final String URI = "/v2/api-docs";

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();
            if (!StringUtils.endsWithIgnoreCase(path,URI )) {
                return chain.filter(exchange);
            }
            String basePath = path.substring(0, path.lastIndexOf(URI));
            ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}

网关的演示项目中添加的网关依赖是:



    org.springframework.cloud
    spring-cloud-starter-gateway

 由于配置了knife4j的配置,需要添加一个控制器,所以需要添加SpringMVC的依赖


    org.springframework.boot
    spring-boot-starter-web

当两个依赖在同一项目中,启动会报错

因为SpringMvc框架中自带一个Tomcat服务器,

而SpringGateway框架中自带一个Netty的服务器

所以在启动项目时,两个框架中的服务器都想占用相同端口,会因为争夺端口主动权出现异常

要想能够正常启动则需要添加yml配置:

spring:
  main:
    web-application-type: reactive

添加此配置后,Tomcat服务器会变成非阻塞的运行 



 

你可能感兴趣的:(网关配置,微服务,架构)