2013-07-30 136 views
66

我注意到下面的代碼是將用戶重定向到項目中的URL,重定向從控制器動作的外部URL在Spring MVC

@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,無論它在它還是不是一個有效的協議,並且不希望重定向到一個視圖。我怎樣才能做到這一點?

感謝,

回答

117

你可以用兩種方法做到這一點。

第一:

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

二:如果你的重定向目標與/開始

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

    } 
+15

如果你直接返回一個String而不是ModelAndView,它就更簡單了。 –

+17

看來,在第一種方法中,你應該設置返回代碼爲302.否則服務器會返回一個代碼爲200的響應,並且在我的情況下(Firefox 41.0)不會導致重定向。 –

+0

我們是否也可以在重定向到外部URL期間添加cookie。 – Srikar

3

您是否嘗試過RedirectView,您可以在其中提供contextRelative參數?

+0

這對於啓動(或沒有)路徑參數很有用'/'檢查它是否應該是相對於webapp的上下文。重定向請求仍將針對同一主機。 –

37

展望實際執行的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; 
} 
+0

但通過這種方式重定向是一個GET或者它仍然是一個POST?我如何重定向爲POST? – Accollativo

+0

實際上,默認情況下,這是返回一個302,這意味着它應該對提供的URL發出GET。對於保持相同方法的重定向,您還應該設置不同的代碼(從HTTP/1.1開始)。但是我非常肯定,如果瀏覽器由於安全問題而使用不同的主機/端口組合來抵禦絕對地址,那麼瀏覽器會阻止它。 –

34

可以使用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

+0

RedirectView是唯一一個似乎爲我工作的人! – James111

+0

我有一個stange behavour wiwth重定向視圖,我得到的webshpere: [code] [27/04/17 13:45:55:385 CDT] 00001303 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E:[錯誤去的servlet] - [DispatcherPrincipal]:java.io.IOException異常:模式不mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect(SecOutputFilter.java:234) \t在使用javax允許 \t。 servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:145)[代碼] –

4

對我來說工作正常:

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

另一種方式來做到這一點就是使用的sendRedirect方法:

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

總之"redirect:yahoo.com""redirect://yahoo.com"會借給你yahoo.com

這裏爲"redirect:yahoo.com"會借給你your-context/yahoo.com即爲前localhost:8080/yahoo.com

+0

兩種溶液具有相同的命令: 「總之‘重定向:yahoo.com’與」,其中的‘重定向:yahoo.com’, 和只有相對的URL重定向正在工作。 – partizanos

相關問題