spring cloud 有不少有用的組件,其中就有大名鼎鼎的 Netflix。從官網截取了一段,看看 spring-cloud Netflix 到底能幹嗎?java
最後一行就涉及到了咱們今天要說的路由過濾功能(Router and Filter)。spring
咱們在使用zuul做爲網關Filter的時候,通常全部轉發或者重定向出去的地址 loation 都會被重寫,原來的 host 會被替代。那麼zuul是怎麼作到的呢。請看下列代碼:ide
@Configuration @EnableZuulProxy public class ZuulConfig { @Bean public LocationRewriteFilter locationRewriteFilter() { return new LocationRewriteFilter(); } }
原來zool是經過 LocationRewriteFilter 這個過濾器重寫全部的請求地址。ui
源碼截取以下:this
@Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); Route route = routeLocator.getMatchingRoute(urlPathHelper.getPathWithinApplication(ctx.getRequest())); if (route != null) { Pair<String, String> lh = locationHeader(ctx); if (lh != null) { String location = lh.second(); URI originalRequestUri = UriComponentsBuilder .fromHttpRequest(new ServletServerHttpRequest(ctx.getRequest())) .build().toUri(); UriComponentsBuilder redirectedUriBuilder = UriComponentsBuilder.fromUriString(location); UriComponents redirectedUriComps = redirectedUriBuilder.build(); //獲取新地址 String newPath = getRestoredPath(this.zuulProperties, route,redirectedUriComps); String modifiedLocation = redirectedUriBuilder.scheme(originalRequestUri.getScheme()) .host(originalRequestUri.getHost()) .port(originalRequestUri.getPort()).replacePath(newPath).build() .toUriString();//用新的地址替換當前請求的地址。 lh.setSecond(modifiedLocation); } } return null; }
若是某些重定向地址不想被路由到怎麼辦?url
那麼咱們能夠改寫一下 LocationRewriteFilter 的生效規則:code
public class ExtendedLocationRewriteFilter extends LocationRewriteFilter { @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); int statusCode = ctx.getResponseStatusCode(); boolean isRedirect = ctx.getZuulResponseHeaders().contains(new Pair("isRedirect","true")); return !isRedirect && HttpStatus.valueOf(statusCode).is3xxRedirection(); } }
即在重定向的時候,在header裏添加識別條件,而後 ExtendedLocationRewriteFilter 判斷是否獲取到此條件。blog
response.setHeader("isRedirect","true");