Spring Cloud zuul 集成Swagger API
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.7.0</version> </dependency>
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.7.0</version> </dependency>
|
- 创建Swagger 文档资源描述 实现 SwaggerResourcesProvider
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package com.test.swagger;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.netflix.zuul.filters.Route; 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 GatewaySwaggerResourcesProvider implements SwaggerResourcesProvider {
private final Logger log = LoggerFactory.getLogger(GatewaySwaggerResourcesProvider.class);
private final RouteLocator routeLocator;
private final DiscoveryClient discoveryClient;
public GatewaySwaggerResourcesProvider(RouteLocator routeLocator, DiscoveryClient discoveryClient) { this.routeLocator = routeLocator; this.discoveryClient = discoveryClient; }
@Override public List<SwaggerResource> get() { List<SwaggerResource> resources = new ArrayList<SwaggerResource>(); resources.add(swaggerResource("default", "/v2/api-docs")); List<Route> routes = routeLocator.getRoutes(); for (Route route : routes) { resources.add(swaggerResource(route.getId(), route.getFullPath().replace("**", "v2/api-docs"))); } return resources; }
private SwaggerResource swaggerResource(String name, String location) { SwaggerResource swaggerResource = new SwaggerResource(); swaggerResource.setName(name); swaggerResource.setLocation(location); swaggerResource.setSwaggerVersion("2.0"); return swaggerResource; } }
|
这里通过get() 函数,往SwaggerResource 添加多个服务的路由
- 继承zuul SendResponseFilter 重写URL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| package com.test.swagger;
import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.zuul.context.RequestContext; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter; import springfox.documentation.swagger2.web.Swagger2Controller;
import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.LinkedHashMap; import java.util.zip.GZIPInputStream;
public class SwaggerBasePathRewritingFilter extends SendResponseFilter {
private final Logger log = LoggerFactory.getLogger(SwaggerBasePathRewritingFilter.class);
private ObjectMapper mapper = new ObjectMapper();
@Override public String filterType() { return "post"; }
@Override public int filterOrder() { return 100; }
@Override public boolean shouldFilter() { return RequestContext.getCurrentContext().getRequest().getRequestURI().endsWith(Swagger2Controller.DEFAULT_URL); }
@Override public Object run() { RequestContext context = RequestContext.getCurrentContext();
if (!context.getResponseGZipped()) { context.getResponse().setCharacterEncoding("UTF-8"); }
String rewrittenResponse = rewriteBasePath(context); context.setResponseBody(rewrittenResponse); return null; }
private String rewriteBasePath(RequestContext context) { InputStream responseDataStream = context.getResponseDataStream();
String requestUri = RequestContext.getCurrentContext().getRequest().getRequestURI(); try { if (context.getResponseGZipped()) { responseDataStream = new GZIPInputStream(context.getResponseDataStream()); } String response = IOUtils.toString(responseDataStream, StandardCharsets.UTF_8); if (response != null) { LinkedHashMap<String, Object> map = this.mapper.readValue(response, LinkedHashMap.class);
String basePath = requestUri.replace(Swagger2Controller.DEFAULT_URL,""); map.put("basePath",basePath); log.debug("Swagger-docs: rewritten Base URL with correct micro-service route: {}", basePath); return mapper.writeValueAsString(map); } } catch (IOException e) { log.error("Swagger-docs filter error", e); } return null; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package com.test.swagger;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.ResponseEntity; import org.springframework.util.StopWatch; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket;
import static springfox.documentation.builders.PathSelectors.regex;
@Configuration public class GatewayConfiguration {
@Configuration public static class SwaggerBasePathRewritingConfiguration {
@Bean public SwaggerBasePathRewritingFilter swaggerBasePathRewritingFilter(){
return new SwaggerBasePathRewritingFilter(); } }
@Bean public Docket swaggerSpringfoxDocket() { StopWatch watch = new StopWatch(); watch.start();
Docket docket = new Docket(DocumentationType.SWAGGER_2) .forCodeGeneration(true) .directModelSubstitute(java.nio.ByteBuffer.class, String.class) .genericModelSubstitutes(ResponseEntity.class) .select() .paths(regex("/api/.*")) .build(); watch.stop(); return docket; }
}
|
本文参考Jhipster网关设计
详情:请了解 Jhipster: 官网网址
转载 jkutner@jhipster-gateway-sample