Redirigir a una URL externa desde la acción del controlador en Spring MVC


He notado que el siguiente código está redirigiendo al Usuario a una URL dentro del proyecto,

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

Considerando que, lo siguiente se redirige correctamente como se pretende, pero requiere 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;
    }

Quiero que la redirección siempre redirija a la URL especificada, ya sea que tenga un protocolo válido en ella o no y no quiero redirigir a una vista. ¿Cómo puedo hacer eso?

Gracias,

Author: Jake, 2013-07-30

8 answers

Puedes hacerlo de dos maneras.

Primero:

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

Segundo:

@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
    return new ModelAndView("redirect:" + projectUrl);
}
 133
Author: Rinat Mukhamedgaliev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-02 06:35:56

Mirando la implementación real de UrlBasedViewResolver y RedirectView la redirección siempre será contextRelativa si su destino de redirección comienza con /. Así que también enviando un //yahoo.com/path/to/resource no ayudaría conseguir un redireccionamiento relativo del protocolo.

Así que para lograr lo que estás intentando puedes hacer algo como:

@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;
}
 42
Author: daniel.eichten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-05 08:56:21

Puede usar el RedirectView. Copiado del JavaDoc :

Vista que redirige a una URL absoluta, relativa al contexto o relativa a la solicitud actual

Ejemplo:

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

También puede usar un ResponseEntity, por ejemplo,

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

Y por supuesto, regresa redirect:http://www.yahoo.com como han mencionado otros.

 40
Author: matsev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-16 21:11:13

Otra forma de hacerlo es usar el método sendRedirect:

@RequestMapping(
    value = "/",
    method = RequestMethod.GET)
public void redirectToTwitter(HttpServletResponse httpServletResponse) throws IOException {
    httpServletResponse.sendRedirect("https://twitter.com");
}
 16
Author: Ivan Mushketyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-04 19:33:32

Para url externas tienes que usar " http://www.yahoo.com " como la url de redirección.

Esto se explica en el prefijo redirect: de la documentación de referencia de Spring.

Redirect:/myapp/some / resource

Se redirigirá en relación con el contexto Servlet actual, mientras que un nombre como

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

Redirigirá a una URL absoluta

 7
Author: sreeprasad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-30 20:38:53

Para mí funciona 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);
}
 4
Author: Lord Nighton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-30 08:19:25

¿Ha intentado RedirectView donde puede proporcionar el parámetro contextRelative?

 3
Author: Vijay Kukkala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-30 20:54:54

En breve "redirect:yahoo.com" o "redirect://yahoo.com" te prestará a yahoo.com.

Donde como "redirect:yahoo.com" te prestará your-context/yahoo.com es decir, para ex - localhost:8080/yahoo.com

 -2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-27 06:20:53