zoukankan      html  css  js  c++  java
  • 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转发修改完成..

  • 相关阅读:
    Rotation Kinematics
    离职 mark
    PnP 问题方程怎么列?
    DSO windowed optimization 代码 (4)
    Adjoint of SE(3)
    IMU 预积分推导
    DSO windowed optimization 代码 (3)
    DSO windowed optimization 代码 (2)
    OKVIS 代码框架
    DSO windowed optimization 代码 (1)
  • 原文地址:https://www.cnblogs.com/liboware/p/12573709.html
Copyright © 2011-2022 走看看