Redirection vers une URL externe à partir de l'action du contrôleur dans Spring MVC

118

J'ai remarqué que le code suivant redirige l'utilisateur vers une URL à l'intérieur du projet,

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

alors que ce qui suit redirige correctement comme prévu, mais nécessite http: // ou 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;
    }

Je veux que la redirection soit toujours redirigée vers l'URL spécifiée, qu'elle contienne ou non un protocole valide et ne souhaite pas rediriger vers une vue. Comment puis je faire ça?

Merci,

Jake
la source

Réponses:

208

Vous pouvez le faire de deux manières.

Première:

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

Seconde:

@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
    return new ModelAndView("redirect:" + projectUrl);
}
Rinat Mukhamedgaliev
la source
19
C'est encore plus simple si vous retournez directement une chaîne plutôt que ModelAndView.
daniel.eichten
24
Il semble que dans la première méthode, vous devez définir le code de retour sur 302. Sinon, un serveur renverrait une réponse avec le code 200 et l'en-tête Location qui ne provoque pas de redirection dans mon cas (Firefox 41.0).
Ivan Mushketyk
Pouvons-nous également ajouter des cookies lors de la redirection vers une URL externe.
Srikar
1
La première méthode nécessite@ResponseStatus(HttpStatus.FOUND)
lapkritinis
@Rinat Mukhamedgaliev Dans ce ModelAndView ("redirect:" + projectUrl); Déclaration quelle serait la clé sera prise par défaut, si la chose ajoutée est de la valeur?
JAVA
56

Vous pouvez utiliser le RedirectView. Copié à partir du JavaDoc :

Vue qui redirige vers une URL relative de requête absolue, relative au contexte ou actuelle

Exemple:

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

Vous pouvez également utiliser un ResponseEntity, par exemple

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

Et bien sûr, revenez redirect:http://www.yahoo.comcomme mentionné par d'autres.

matsev
la source
Le RedirectView était le seul qui semblait fonctionner pour moi!
James111
J'ai un comportement étrange avec Redirect View, sur webshpere je reçois: [code] [27/04/17 13: 45: 55: 385 CDT] 00001303 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E : [Erreur de servlet] - [DispatcherPrincipal]: java.io.IOException: modèle non autorisé sur mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect (SecOutputFilter.java:234) sur javax.servlet.httraSponseResponse .Http.Response sendRedirect (HttpServletResponseWrapper.java:145) [code]
Carlos de Luna Saenz
49

En examinant l' implémentation réelle de UrlBasedViewResolver et RedirectView, la redirection sera toujours contextRelative si votre cible de redirection commence par /. Donc, envoyer également un //yahoo.com/path/to/resource n'aiderait pas à obtenir une redirection relative au protocole.

Donc, pour réaliser ce que vous essayez, vous pouvez faire quelque chose comme:

@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;
}
daniel.eichten
la source
Mais de cette façon, la redirection est un GET ou reste-t-elle un POST? Comment rediriger en POST?
Accollativo
En fait, par défaut, cela renvoie un 302, ce qui signifie qu'il devrait émettre un GET contre l'url fournie. Pour la redirection en conservant la même méthode, vous devez également définir un code différent (307 à partir de HTTP / 1.1). Mais je suis à peu près sûr que les navigateurs bloqueront cela si cela va à l'encontre d'une adresse absolue utilisant une combinaison hôte / port différente en raison de problèmes de sécurité.
daniel.eichten
26

Une autre façon de le faire est simplement d'utiliser la sendRedirectméthode:

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

Vous pouvez le faire de manière assez concise en utilisant ResponseEntitycomme ceci:

  @GetMapping
  ResponseEntity<Void> redirect() {
    return ResponseEntity.status(HttpStatus.FOUND)
        .location(URI.create("http://www.yahoo.com"))
        .build();
  }
k13i
la source
1
Cela devrait être la réponse acceptée. Extrêmement facile à installer et à utiliser.
cyberbit
9

Pour moi fonctionne bien:

@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);
}
Lord Nighton
la source
Je pense que cette méthode est meilleure que RedirectView car elle fonctionne également dans le facteur.
mehdi mohammadi
3

Avez-vous essayé RedirectView où vous pouvez fournir le paramètre contextRelative?

Vijay Kukkala
la source
Ce paramètre est utile pour les chemins qui commencent (ou non) par /pour vérifier s'il doit être relatif au contexte de l'application Web. La demande de redirection sera toujours pour le même hôte.
Sotirios Delimanolis
-2

En bref "redirect://yahoo.com"vous prêtera yahoo.com.

où comme "redirect:yahoo.com"vous prêtera your-context/yahoo.comie pour ex-localhost:8080/yahoo.com

hd1
la source
les deux solutions ont la même commande: "En bref" redirect: yahoo.com "vs" où comme "redirect: yahoo.com", et seule la redirection relative de l'url fonctionne.
partizanos