spring-cloud Netflix 如何實現路由功能的

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");
相關文章
相關標籤/搜索