web-dev-qa-db-fra.com

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

J'ai remarqué que le code suivant redirige l'utilisateur vers une URL 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 redirige toujours 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,

91
Jake

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

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

Vue qui redirige vers une URL absolue, relative par rapport au contexte ou relative à la demande 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, retournez redirect:http://www.yahoo.com comme mentionné par d'autres.

50
matsev

En regardant dans l'implémentation réelle de rlBasedViewResolver et RedirectView , la redirection sera toujours contextRelative si votre cible de redirection commence par /. Par conséquent, l'envoi d'un //yahoo.com/path/to/resource ne vous 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;
}
48
daniel.eichten

Une autre façon de faire consiste simplement à utiliser la méthode sendRedirect:

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

Pour les URL externes, vous devez utiliser " http://www.yahoo.com " comme URL de redirection.

Ceci est expliqué dans la documentation de référence redirect: préfixe de Spring.

redirection:/myapp/some/resource

redirigera par rapport au contexte actuel du servlet, alors qu'un nom tel que

redirection: http://myhost.com/some/arbitrary/path

va rediriger vers une URL absolue

8
sreeprasad

Pour moi, ça marche 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);
}
6
Lord Nighton

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

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

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

3
Vijay Kukkala