Spring Cloud Zuul:RedirectView 重定向到服务而不是网关

Spring Cloud Zuul: RedirectView redirecting to service and not gateway

我对微服务有点陌生 Spring。我有 Spring 云微服务(端口:8xxx-8xxx),在端口 9000 上有一个 Zuul 网关 运行。在 UI 服务的控制器中有一个方法应该先登录,然后return 到 index.html 页面:

@RequestMapping(value="/do-login", method = RequestMethod.POST)
    public RedirectView doLogin (@ModelAttribute("authEntity") final AuthEntity authEntity, final Model model) {
        model.addAttribute(VERSION, applicationVersion);
        model.addAttribute("authEntity", new AuthEntity());
        authenticatedStatus = true;
        model.addAttribute(AUTHENTICATED, authenticatedStatus);

        return new RedirectView("index");
    }

问题是,当上述方法完成时,它 return 是微服务本身的 url localhost:8888/index 但不是 localhost:9000/services/ui/

如果我用更简单的方法:

@RequestMapping(value="/do-login", method = RequestMethod.POST)
public String doLogin (@ModelAttribute("authEntity") final AuthEntity authEntity, final Model model) {
    model.addAttribute(VERSION, applicationVersion);
    model.addAttribute("authEntity", new AuthEntity());
    authenticatedStatus = true;
    model.addAttribute(AUTHENTICATED, authenticatedStatus);

    return "index";
}

这 return 正确地是网关 localhost:9000/services/ui/do-login 的 url,但带有我不需要的 /do-login

也许我可以删除 url 的 /do-login/ 部分?或者也许有解决错误重定向的方法?

提前致谢!

如果您像 return "index"; 那样使用相对路径,发送到 http://localhost:9000/services/ui/do-loginPOST 请求的结果将包括 URL 到 http://localhost:9000/... 除非编码否则在 jsp/freemarker/thymeleaf 文件中。

如果您想摆脱 do-login,您需要实施所谓的 Post 后重定向(或表单提交后重定向)方法,这样页面刷新就不会发生重新提交表格。如果你采用这种方法,这似乎是你在使用时所做的:return new RedirectView("index");,我可以想到几种修复 URL 并将其设置为代理主机的方法。

1) http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/RedirectView.html,有几个构造函数接受主机参数,您需要在控制器中注入代理主机 class 并且最有可能在每个控制器中注入 class 在 Post.

之后实现重定向

2) http://tuckey.org/urlrewrite/, 包含 UrlRewriteFilter 并配置规则以在 webapp http 状态代码响应为 302 时从 webapp 主机重写到代理主机。使用这种方法它只会是一次规则并且不需要注入代理主机到控制器 classes 或更改 return new RedirectView("index");`

3) 也许这个重写是在 Zuul 中实现的,您不需要按照 2).

中的建议包含和配置 UrlRewriteFilter

作为旁注,我过去曾将 Nginx 的 proxy_pass 配置为 Java 网络应用程序(我在 Post 之后实现了重定向),但我不记得有这个问题。必须查看 UrlRewriteFilterNginx 配置文件以对此进行扩展。

我发现这个(感谢在这里回答:Spring redirect url issue when behind Zuul proxy)似乎可以按要求工作(但被认为是 'workaround'):

@RequestMapping(value="/do-login", method = RequestMethod.POST)
    public void doLogin (@ModelAttribute("authEntity") final AuthEntity authEntity,
                         final Model model,
                         HttpServletResponse servletResponse) throws IOException {
        ...

        String rUrl = ServletUriComponentsBuilder.fromCurrentContextPath().path("/").build().toUriString();
        servletResponse.sendRedirect(rUrl);
    }