从Spring MVC中的控制器操作重定向到外部URL


118

我注意到以下代码将用户重定向到项目内的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,无论它是否具有有效协议,并且都不想重定向到视图。我怎样才能做到这一点?

谢谢,

Answers:


207

您可以通过两种方式做到这一点。

第一:

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

19
如果您直接返回String而不是ModelAndView,则更为简单。
daniel.eichten

24
似乎在第一种方法中,您应该将返回码设置为302。否则,服务器将返回带有代码200和Location标头的响应,在我的情况下,该响应不会导致重定向(Firefox 41.0)。
伊万·穆什凯奇

我们也可以在重定向到外部URL期间添加cookie。
斯里卡,

1
第一种方法需要@ResponseStatus(HttpStatus.FOUND)
lapkritinis

@Rinat Mukhamedgaliev在此ModelAndView(“ redirect:” + projectUrl); 如果添加的值是值,则声明将默认键为默认值?
JAVA

56

您可以使用RedirectView。从JavaDoc复制:

重定向到绝对,上下文相关或当前请求相关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像其他人提到的那样返回。


RedirectView是唯一为我工作的视图!
James111 '16

我在Webshpere上使用重定向视图时感觉很烂,我得到:[代码] [27/04/17 13:45:55:385 CDT] 00001303 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E :[错误servlet]-[DispatcherPrincipal]:java.io.IOException:在javax.servlet.http.HttpServletResponseWrapper上的mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect(SecOutputFilter.java:234)不允许使用模式。 sendRedirect(HttpServletResponseWrapper.java:145)[code]
Carlos de Luna Saenz

49

如果您的重定向目标以/开头,则在研究UrlBasedViewResolverRedirectView的实际实现时,重定向始终为contextRelative。因此,发送//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;
}

但是通过这种方式,重定向是GET还是保持POST?如何重定向为POST?
Accollat​​ivo '16

好吧,实际上默认情况下,这将返回302,这意味着它应该针对提供的URL发出GET。为了使重定向保持相同的方法,您还应该设置不同的代码(从HTTP / 1.1开始为307)。但是我非常确定,如果由于安全问题,如果浏览器使用不同的主机/端口组合来违反绝对地址,则浏览器将阻止此操作。
daniel.eichten '16

26

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

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

21

您可以使用ResponseEntity以下方法以非常简洁的方式执行此操作:

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

1
这应该是公认的答案。极其容易设置和使用。
cyberbit

9

对我来说效果很好:

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

我认为此方法比RedirectView更好,因为它也在邮递员中工作。
mehdi mohammadi



-2

总之"redirect://yahoo.com"会借给你的yahoo.com

哪里"redirect:yahoo.com"可以借给您your-context/yahoo.com,例如localhost:8080/yahoo.com


两种解决方案都具有相同的命令:“总之,“ redirect:yahoo.com”与“ where as” redirect:yahoo.com“,只有相对的URL重定向有效。
partizanos
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.