Reindirizza a un URL esterno dall'azione del controller in Spring MVC


118

Ho notato che il seguente codice reindirizza l'utente a un URL all'interno del progetto,

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

considerando che, quanto segue reindirizza correttamente come previsto, ma richiede http: // o 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;
    }

Voglio che il reindirizzamento reindirizzi sempre all'URL specificato, indipendentemente dal fatto che contenga un protocollo valido o meno e non voglio reindirizzare a una vista. Come lo posso fare?

Grazie,

Risposte:


208

Puoi farlo in due modi.

Primo:

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

Secondo:

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

19
È ancora più semplice se restituisci direttamente una stringa anziché ModelAndView.
daniel.eichten

24
Sembra che nel primo metodo dovresti impostare il codice di ritorno a 302. Altrimenti un server restituirebbe una risposta con codice 200 e intestazione Location che non causa il reindirizzamento nel mio caso (Firefox 41.0).
Ivan Mushketyk

Possiamo anche aggiungere cookie durante il reindirizzamento a URL esterno.
Srikar

1
Il primo metodo richiede@ResponseStatus(HttpStatus.FOUND)
lapkritinis

@Rinat Mukhamedgaliev In questo ModelAndView ("redirect:" + projectUrl); Dichiarazione quale sarebbe la chiave verrà presa come predefinita, se la cosa aggiunta è il valore?
JAVA

56

Puoi usare il file RedirectView. Copiato da JavaDoc :

Vista che reindirizza a un URL relativo della richiesta assoluto, relativo al contesto o corrente

Esempio:

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

Puoi anche usare ResponseEntity, ad es

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

E, naturalmente, ritorna redirect:http://www.yahoo.comcome menzionato da altri.


Il RedirectView era l'unico che sembrava funzionare per me!
James111

Sto avendo un comportamento strano con la visualizzazione di reindirizzamento, su webshpere ricevo: [codice] [27/04/17 13: 45: 55: 385 CDT] 00001303 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E : [Error de servlet] - [DispatcherPrincipal]: java.io.IOException: pattern non consentito in mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect (SecOutputFilter.java:234) su javax.servlet.httraletp.Http. sendRedirect (HttpServletResponseWrapper.java:145) [code]
Carlos de Luna Saenz

49

Esaminando l'implementazione effettiva di UrlBasedViewResolver e RedirectView, il reindirizzamento sarà sempre contextRelative se il target di reindirizzamento inizia con /. Quindi anche l'invio di un //yahoo.com/path/to/resource non aiuta a ottenere un reindirizzamento relativo al protocollo.

Quindi, per ottenere ciò che stai cercando, potresti fare qualcosa come:

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

Ma in questo modo il redirect è un GET o resta un POST? Come faccio a reindirizzare come POST?
Accollativo

In realtà, per impostazione predefinita, questo restituisce un 302, il che significa che dovrebbe emettere un GET contro l'URL fornito. Per il reindirizzamento mantenendo lo stesso metodo dovresti anche impostare un codice diverso (307 da HTTP / 1.1). Ma sono abbastanza sicuro che i browser lo bloccheranno se va contro un indirizzo assoluto utilizzando una diversa combinazione host / porta a causa di problemi di sicurezza.
daniel.eichten

26

Un altro modo per farlo è semplicemente usare il sendRedirectmetodo:

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

22

Puoi farlo in modo abbastanza conciso usando in ResponseEntityquesto modo:

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

1
Questa dovrebbe essere la risposta accettata. Estremamente facile da configurare e utilizzare.
cyberbit

9

Per me funziona bene:

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

Penso che questo metodo sia migliore di RedirectView in quanto funziona anche nel postino.
mehdi mohammadi


3

Hai provato RedirectView dove puoi fornire il parametro contextRelative?


Questo parametro è utile per i percorsi che iniziano (o non iniziano) con /per verificare se dovrebbe essere relativo al contesto della webapp. La richiesta di reindirizzamento sarà ancora per lo stesso host.
Sotirios Delimanolis

-2

In breve "redirect://yahoo.com"ti presterà yahoo.com.

dove come "redirect:yahoo.com"ti presterà ad your-context/yahoo.comesempio per ex-localhost:8080/yahoo.com


entrambe le soluzioni hanno lo stesso comando: "In short" redirect: yahoo.com "vs" dove come "redirect: yahoo.com", e funziona solo il reindirizzamento relativo all'URL.
partizanos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.