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");