首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Zuul代理中进行URL重写?

问如何在Zuul代理中进行URL重写?
EN

Stack Overflow用户
提问于 2015-08-05 10:24:29
回答 3查看 13.9K关注 0票数 4

我的Zuul过滤器中的一个请求是URI /hello/World,我想重定向到/myapp/test。此/myapp/test是在尤里卡注册的服务。

代码语言:javascript
复制
zuul:
  routes:
     xyz:
         path: /hello/World
         url: http://localhost:1234/myapp/test
         stripPrefix: true

当我尝试上述配置时,传入的URI将后缀到配置好的URL (如http://localhost:1234/myapp/test/World )。我遇到的链接中,很少有提到在Zuul中还没有URL重写功能。

在Zuul层还有其他方法可以这样做吗?

备注:此时,我不能在one服务器或任何其他层进行反向代理,因为我的Zuul过滤器是直接接收请求的过滤器。

EN

回答 3

Stack Overflow用户

发布于 2019-05-18 20:52:57

使用@Adelin解决方案,但没有什么改进

使用“Url”属性作为用于自定义Url重写的路径(在我的示例中禁用了Eureka ):

代码语言:javascript
复制
ribbon.eureka.enabled=false

zuul.routes.route1.path=/route1/**
zuul.routes.route1.serviceId=service1
zuul.routes.route1.url=/path/to/prepend

service1.ribbon.listOfServers=http://server1

然后实现以下过滤器:

代码语言:javascript
复制
/**
 * Fixing missing URL rewriting when using ribbon
 */
@Component
public class CustomPathZuulFilter extends ZuulFilter {

    @Autowired
    private ZuulProperties zuulProperties;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
    }

    @Override
    public boolean shouldFilter() {
        // override PreDecorationFilter only if executed previously successfully
        return RequestContext.getCurrentContext().getFilterExecutionSummary().toString()
                .contains("PreDecorationFilter[SUCCESS]");
    }

    @Override
    public Object run() {
        final RequestContext context = RequestContext.getCurrentContext();
        if (context.get(FilterConstants.SERVICE_ID_KEY) == null || context.getRouteHost() != null) {
            // not a Ribbon route
            return null;
        }

        // get current ZuulRoute
        final String proxy = (String) context.get(FilterConstants.PROXY_KEY);
        final ZuulRoute zuulRoute = this.zuulProperties.getRoutes().get(proxy);

        // patch URL by prefixing it with zuulRoute.url
        final Object originalRequestPath = context.get(FilterConstants.REQUEST_URI_KEY);
        final String modifiedRequestPath = zuulRoute.getUrl() + originalRequestPath;
        context.put(FilterConstants.REQUEST_URI_KEY, modifiedRequestPath);

        // patch serviceId because :
        // - has been set to route.location in PreDecorationFilter
        // - route.location has been set to zuulRoute.location in SimpleRouteLocator
        // - zuulRoute.location return zuulRoute.url if set
        context.set(FilterConstants.SERVICE_ID_KEY, zuulRoute.getServiceId());

        return null;
    }
}

现在,对/route1的调用将被代理为http://server1/path/to/prepend

此解决方案还与不使用丝带的共存路线兼容。

不使用丝带的共存路线的示例:

代码语言:javascript
复制
zuul.routes.route2.path=/route2/**
zuul.routes.route2.url=http://server2/some/path

对/route2的调用将由SimpleHostRoutingFilter代理到http://server2/some/path (如果没有禁用)

票数 4
EN

Stack Overflow用户

发布于 2018-10-29 21:40:13

以下是@Vikash在链接中发布的解决方案

代码语言:javascript
复制
@Component
public class CustomPathZuulFilter extends ZuulFilter
{
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return PreDecorationFilter.FILTER_ORDER + 1;
    }

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

    @Override
    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        Object originalRequestPath = context.get(REQUEST_URI_KEY);
        String modifiedRequestPath = "/api/microservicePath" + originalRequestPath;
        context.put(REQUEST_URI_KEY, modifiedRequestPath);

        return null;
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-03-23 14:42:33

您是否尝试过创建预过滤器,甚至创建路由筛选器?

这样,您就可以拦截请求,并更改路由。

请参阅Zuul滤波器

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31829773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档