springcloud zuul 过滤器修改转发的url
使用了springcloud 后,自然就会使用到 zuul网关来转发相应的请求到对应的微服务上去.使用zuul 的过滤器可以校验一些接口的权限访问,自然有时候也需要对某些url规则的进行一些相应的转发操作,这样可以让前端不知道你后端的真实路劲,也可以适应自己的一些需求.先贴上转发的代码.import java.util.HashMap;import java.util.Map;...
使用了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.
下面来分析下zuul的源码.
首先
在 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转发修改完成..
更多推荐
所有评论(0)