使用了springcloud 后,自然就會使用到 zuul網關來轉發相應的請求到對應的微服務上去.使用zuul 的過濾器可以校驗一些接口的權限訪問,自然有時候也需要對某些url規則的進行一些相應的轉發操作,這樣可以讓前端不知道你后端的真實路勁,也可以適應自己的一些需求.先貼上轉發時修改url的代碼.
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
@Component
public class UrlRedirectFilter extends ZuulFilter implements AbstractLogger{
/**
* 重定向的規則,根據key來重定向到val.
*/
private static Map<String, String>urlMap=new HashMap<>();
static {
urlMap.put("t", "/test/");
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String url = request.getRequestURI(); // 列子 [/user/login/loginWx]
String[] split = url.split("/", 3); // 這里切割一下,好讓下面判斷是否是需要修改url的.
if (split.length>=2) {
String val = urlMap.get(split[1]);
if (StringUtils.isNotEmpty(val)) {
url=url.replaceFirst("/"+split[1]+"/", val);// 根據配置好的去將url替換掉,這里可以寫自己的轉換url的規則
ctx.put(FilterConstants.REQUEST_URI_KEY, url); // 將替換掉的url set進去,在對應的轉發請求的url就會使用這個url
}
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
//filterOrder:過濾的順序
@Override
public int filterOrder() {
return 1;
}
/* (non-Javadoc)filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命周期的過濾器類型,具體如下:
pre:路由之前
routing:路由之時
post: 路由之后
error:發送錯誤調用
*/
@Override
public String filterType() {
return FilterConstants.ROUTE_TYPE;
}
}
我這里使用了zuul的過濾器來攔截 修改轉發的url , 代碼中是 設定了在 路由之時 過濾,這個地方特別重要,一定是路由之時,不然是沒有效果的.然后 是在路由之時 第1個 去修改這個轉發的url ,並且每次都會進run方法,因為 shouldFilter() 永遠給的是true.
首先
在 org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter 這個根據uri決定調用哪一個route 的過濾器中有ctx.put(REQUEST_URI_KEY, route.getPath()); 這行代碼,也就在這put了一次這個url對應的值, 我們將url修改后再put 進去,zuul 將會在轉發的時候,也就是 SendForwardFilter 這個里面 (貼一段源碼)
@Override
public Object run() {
try {
RequestContext ctx = RequestContext.getCurrentContext();
String path = (String) ctx.get(FORWARD_TO_KEY);
RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(path);
if (dispatcher != null) {
ctx.set(SEND_FORWARD_FILTER_RAN, true);
if (!ctx.getResponse().isCommitted()) {
dispatcher.forward(ctx.getRequest(), ctx.getResponse());
ctx.getResponse().flushBuffer();
}
}
}catch (Exception ex) {
ReflectionUtils.rethrowRuntimeException(ex);
}
return null;
}
這里 取的是 FORWARD_TO_KEY 這個key所存儲的url .也就是最終轉發的url值.
至此,url轉發修改完成..
