Von der Controller-Aktion in Spring MVC zu einer externen URL umleiten

117

Ich habe festgestellt, dass der folgende Code den Benutzer zu einer URL innerhalb des Projekts umleitet.

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

Im Folgenden wird die ordnungsgemäße Umleitung wie beabsichtigt durchgeführt, erfordert jedoch http: // oder 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;
    }

Ich möchte, dass die Umleitung immer zu der angegebenen URL umleitet, unabhängig davon, ob sie ein gültiges Protokoll enthält oder nicht, und ich möchte nicht zu einer Ansicht umleiten. Wie kann ich das machen?

Vielen Dank,

Jake
quelle

Antworten:

206

Sie können dies auf zwei Arten tun.

Zuerst:

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

Zweite:

@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
    return new ModelAndView("redirect:" + projectUrl);
}
Rinat Mukhamedgaliev
quelle
19
Es ist noch einfacher, wenn Sie direkt einen String zurückgeben, anstatt ModelAndView.
daniel.eichten
24
Es scheint, dass Sie bei der ersten Methode den Rückkehrcode auf 302 setzen sollten. Andernfalls würde ein Server eine Antwort mit Code 200 und Location-Header zurückgeben, die in meinem Fall keine Umleitung verursacht (Firefox 41.0).
Ivan Mushketyk
Können wir auch Cookies während der Umleitung zur externen URL hinzufügen?
Srikar
1
Erste Methode erfordert@ResponseStatus(HttpStatus.FOUND)
Lapkritinis
@Rinat Mukhamedgaliev In diesem ModelAndView ("redirect:" + projectUrl); Aussage, was der Schlüssel wäre, wird als Standard genommen, wenn der Mehrwert Wert ist?
JAVA
56

Sie können die verwenden RedirectView. Aus dem JavaDoc kopiert :

Ansicht, die zu einer absoluten, kontextbezogenen oder aktuellen anforderungsrelativen URL umleitet

Beispiel:

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

Sie können auch a verwenden ResponseEntity, z

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

Und natürlich kehren Sie zurück, redirect:http://www.yahoo.comwie von anderen erwähnt.

matsev
quelle
Das RedirectView war das einzige, das für mich zu funktionieren schien!
James111
Ich habe ein seltsames Verhalten mit Redirect View. Auf der Webseite erhalte ich Folgendes: [Code] [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: Muster bei mx.isban.security.components.SecOutputFilter nicht zulässig sendRedirect (HttpServletResponseWrapper.java:145) [Code]
Carlos de Luna Saenz
49

Untersuchung der tatsächlichen Implementierung von UrlBasedViewResolver und RedirectView die Umleitung immer kontextabhängig, wenn Ihr Umleitungsziel mit / beginnt. Das Senden einer //yahoo.com/path/to/resource würde also nicht dazu beitragen, eine protokollbezogene Umleitung zu erhalten.

Um das zu erreichen, was Sie versuchen, können Sie Folgendes tun:

@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
quelle
Aber auf diese Weise ist die Weiterleitung ein GET oder bleibt es ein POST? Wie leite ich als POST um?
Accollativo
Tatsächlich gibt dies standardmäßig eine 302 zurück, was bedeutet, dass ein GET für die angegebene URL ausgegeben werden sollte. Um die Umleitung mit derselben Methode durchzuführen, sollten Sie auch einen anderen Code festlegen (307 ab HTTP / 1.1). Aber ich bin mir ziemlich sicher, dass Browser dies blockieren, wenn es aus Sicherheitsgründen gegen eine absolute Adresse mit einer anderen Host / Port-Kombination geht.
daniel.eichten
26

Eine andere Möglichkeit ist die Verwendung der folgenden sendRedirectMethode:

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

Sie können dies auf ziemlich präzise Weise tun, indem Sie Folgendes tun ResponseEntity:

  @GetMapping
  ResponseEntity<Void> redirect() {
    return ResponseEntity.status(HttpStatus.FOUND)
        .location(URI.create("http://www.yahoo.com"))
        .build();
  }
k13i
quelle
1
Dies sollte die akzeptierte Antwort sein. Extrem einfach einzurichten und zu verwenden.
Cyberbit
9

Für mich funktioniert gut:

@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
quelle
Ich denke, diese Methode ist besser als RedirectView, da sie auch beim Postboten funktioniert.
Mehdi Mohammadi
8

Für eine externe URL müssen Sie " http://www.yahoo.com " verwenden " als Weiterleitungs-URL verwenden.

Dies wird im Präfix redirect: der Spring-Referenzdokumentation erläutert .

Weiterleitung: / myapp / some / resource

leitet relativ zum aktuellen Servlet-Kontext um, während ein Name wie z

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

leitet zu einer absoluten URL weiter

sreeprasad
quelle
3

Haben Sie RedirectView ausprobiert, wo Sie den contextRelative-Parameter angeben können?

Vijay Kukkala
quelle
Dieser Parameter ist nützlich für Pfade, mit denen begonnen wird (oder nicht), um /zu überprüfen, ob er relativ zum Webanwendungskontext sein soll. Die Umleitungsanforderung gilt weiterhin für denselben Host.
Sotirios Delimanolis
-2

Kurz gesagt "redirect://yahoo.com", leihen Sieyahoo.com .

wo wie "redirect:yahoo.com"wird Ihnen your-context/yahoo.comzB zB leihenlocalhost:8080/yahoo.com

hd1
quelle
Beide Lösungen haben den gleichen Befehl: "Kurz" Weiterleitung: yahoo.com "vs" wobei "Umleitung: yahoo.com" und nur die relative URL-Umleitung funktioniert.
Partizanos