SpringCloud-Zuul过滤器修改转发的url


  使用了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转发修改完成..

猜你喜欢

转载自www.cnblogs.com/liboware/p/12573709.html