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

  • 相关阅读:
    swoole多进程操作
    LinUX系统ThinkPHP5链接MsSQL数据库的pdo_dblib扩展
    php 访问用友u8数据
    C++/CLI剪辑
    托管代码中调用c++本地代码
    非托管代码中调用托管代码
    Resharper快捷键使用
    Unity3d简便的声音管理方案
    QT离线安装包
    Winform中使用Reactivex代替BeginInvoke/Invoke来更新UI数据
  • 原文地址:https://www.cnblogs.com/liboware/p/12573709.html
Copyright © 2011-2022 走看看