在 SpringMVC 中从控制器操作重定向到外部 URL

我注意到下面的代码正在将用户重定向到项目中的 URL,

@RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "yahoo.com";
return "redirect:" + redirectUrl;
}

然而,下面的代码正在按预期正确地重定向,但是需要 http://或 https://

@RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "http://www.yahoo.com";
return "redirect:" + redirectUrl;
}

我希望重定向总是重定向到指定的 URL,无论它是否有一个有效的协议,并且不希望重定向到一个视图。我该怎么做?

谢谢,

464676 次浏览

对于外部 URL,您必须使用“ http://www.yahoo.com”作为重定向 URL。

这在 Spring 参考文档的 重定向: 前缀中有解释。

Redirect:/myapp/some/resource

将相对于当前 Servlet 上下文重定向,而诸如

重定向: http://myhost.com/some/arbitrary/path

将重定向到一个绝对 URL

您是否尝试了 重定向视图,在那里您可以提供 contextRelativer 参数?

你有两种方法。

第一:

@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public void method(HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", projectUrl);
httpServletResponse.setStatus(302);
}

第二:

@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
return new ModelAndView("redirect:" + projectUrl);
}

查看 UrlBasedViewResolver (基于 UrlBasedViewResolver)重定向视图的实际实现,如果您的重定向目标以/开始,那么重定向将始终是 contextRelant。因此,发送 a// yahoo.com/path/to/resource 也无助于获得协议相对重定向。

所以为了达到你想要的效果,你可以这样做:

@RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = request.getScheme() + "://www.yahoo.com";
return "redirect:" + redirectUrl;
}

你可以使用 RedirectView。复制自 JavaDoc:

重定向到绝对 URL、上下文相对 URL 或当前请求相对 URL 的视图

例如:

@RequestMapping("/to-be-redirected")
public RedirectView localRedirect() {
RedirectView redirectView = new RedirectView();
redirectView.setUrl("http://www.yahoo.com");
return redirectView;
}

你也可以使用 ResponseEntity,例如。

@RequestMapping("/to-be-redirected")
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI yahoo = new URI("http://www.yahoo.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(yahoo);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}

当然,返回其他人提到的 redirect:http://www.yahoo.com

对我来说效果不错:

@RequestMapping (value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI uri = new URI("http://www.google.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(uri);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}

另一种方法是使用 sendRedirect方法:

@RequestMapping(
value = "/",
method = RequestMethod.GET)
public void redirectToTwitter(HttpServletResponse httpServletResponse) throws IOException {
httpServletResponse.sendRedirect("https://twitter.com");
}

简而言之,"redirect://yahoo.com"将借给你 yahoo.com

在哪里作为 "redirect:yahoo.com"将借给你 your-context/yahoo.com即前 localhost:8080/yahoo.com

你可以像下面这样用简洁的方式使用 ResponseEntity:

  @GetMapping
ResponseEntity<Void> redirect() {
return ResponseEntity.status(HttpStatus.FOUND)
.location(URI.create("http://www.yahoo.com"))
.build();
}

这对我很有效,并且解决了“对飞行前请求的响应不能通过访问控制检查...”的问题。

控制员

    RedirectView doRedirect(HttpServletRequest request){


String orgUrl = request.getRequestURL()
String redirectUrl = orgUrl.replaceAll(".*/test/","http://xxxx.com/test/")


RedirectView redirectView = new RedirectView()
redirectView.setUrl(redirectUrl)
redirectView.setStatusCode(HttpStatus.TEMPORARY_REDIRECT)
return redirectView
}


启动安全系统

@EnableWebSecurity
class SecurityConfigurer extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
}
}