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-login
的 POST
请求的结果将包括 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 之后实现了重定向),但我不记得有这个问题。必须查看 UrlRewriteFilter
和 Nginx
配置文件以对此进行扩展。
我发现这个(感谢在这里回答: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);
}
我对微服务有点陌生 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-login
的 POST
请求的结果将包括 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 之后实现了重定向),但我不记得有这个问题。必须查看 UrlRewriteFilter
和 Nginx
配置文件以对此进行扩展。
我发现这个(感谢在这里回答: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);
}