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,

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

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.


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

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

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

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

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?


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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.