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,

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

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.


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

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

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

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

Ich denke, diese Methode ist besser als RedirectView, da sie auch beim Postboten funktioniert.
Mehdi Mohammadi


3

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


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


Beide Lösungen haben den gleichen Befehl: "Kurz" Weiterleitung: yahoo.com "vs" wobei "Umleitung: yahoo.com" und nur die relative URL-Umleitung funktioniert.
Partizanos
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.