使用ZuulFilter轉發路由


背景:項目重構,生產線上url需要按照需要通過網關轉發給不同的service,之前用過自定義路由,在yml文件配置route的方式去做轉發,遇到一個問題那就是 zuul.route.<自定義一個serviceid>.path = /account/**  zuul.route.<自定義一個serviceid>.serviceId=account,但是不能保證請求的url,在/account/后面的url路徑跟 account服務里面的路徑一致,所以這樣會有問題。這樣的話,只能用另外一種方式了,那就是通過filter轉發

1.網關代碼

@Component
public class CommonServicePathFilter extends ZuulFilter {

    private final static String GETWAY_FOWARD_PREFIX="getway_forward_";

    private final static String GETWAY_COMPAY_CONFIG_KEY = "getway_company";

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public String filterType() {
       //這里很重要,必須是route
        return "route";
    }

    @Override
    public int filterOrder() {
        return 1;
    }


    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        String url = ctx.getRequest().getRequestURI();
        Map<String,String> forwardMap =  getForwardMap(url);
        if(forwardMap != null){
            String fowardUrl = forwardMap.get(url);
            String serviceId = getServiceId(fowardUrl);
            String requestUrl = getRequestUrl(fowardUrl,serviceId);
              //1.設置目標service的Controller的路徑
            ctx.put(FilterConstants.REQUEST_URI_KEY,requestUrl);
             //2.設置目標service的serviceId
            ctx.put(FilterConstants.SERVICE_ID_KEY,serviceId);
        }
        return null;
    }
    private String getServiceId(String url){
        if(url.startsWith("/")){
            String temp = url.substring(1);
            return temp.split("/")[0];
        }else{
            return null;
        }
    }

    private String getRequestUrl(String url,String serviceId){
        return url.substring(serviceId.length() +1);
    }

    @Override
    public boolean shouldFilter() {
       return true;
    }



    private Map<String,String> getForwardMap(String originalUrl){
           //todo:這里是返回一個map,傳入一個originUrl,返回一個要轉發的url
    }

}

 

2.坑

 很多網上的資料講需要做到

ctx.put(FilterConstants.REQUEST_URI_KEY,requestUrl);
但是我使用的時候,一直報404,后來跟蹤服務之后,發現其實ctx里面還有一個serviceId的屬性,它是跟當前請求的這個原始url映射的serviceId保持一致的,但是如果你要轉發的serviceId並不是這個的話,那就會報404,所以必須要在這里重新定義serviceId,
 ctx.put(FilterConstants.SERVICE_ID_KEY,serviceId);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM