【问题标题】:Spring Cloud Zuul: RedirectView redirecting to service and not gatewaySpring Cloud Zuul:RedirectView 重定向到服务而不是网关
【发布时间】:2017-10-18 07:52:51
【问题描述】:

我对微服务和 Spring 有点陌生。我有 Spring Cloud 微服务(端口:8xxx-8xxx),Zuul 网关在端口 9000 上运行。UI 服务上的控制器中有一个方法,它应该进行登录,然后返回 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");
    }

问题是,当上述方法完成时,它返回一个微服务本身的 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";
}

这会正确返回网关 localhost:9000/services/ui/do-login 的 URL,但我不需要 /do-login

也许我可以去掉网址中的/do-login/ 部分?或者也许有解决错误重定向的方法?

提前致谢!

【问题讨论】:

    标签: java spring-mvc spring-cloud netflix-zuul


    【解决方案1】:

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

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

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

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

    3) 也许这种重写是在Zuul 中实现的,您不需要像2) 中建议的那样包含和配置UrlRewriteFilter

    顺便说一句,我过去曾将 Nginx 的 proxy_pass 配置为 Java webapps(我在其中实现了 Redirect After Post),但我不记得有这个问题。必须查看 UrlRewriteFilterNginx 配置文件才能对此进行扩展。

    【讨论】:

      【解决方案2】:

      我发现这(感谢在这里回答:Spring redirect url issue when behind Zuul proxy)似乎可以按要求工作(但被认为是“解决方法”):

      @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);
          }
      

      【讨论】:

        猜你喜欢
        • 2021-05-27
        • 2018-08-27
        • 1970-01-01
        • 2021-09-01
        • 2014-10-10
        • 2021-12-12
        • 2016-02-28
        • 2020-05-31
        • 1970-01-01
        相关资源
        最近更新 更多