Alihkan ke URL eksternal dari tindakan pengontrol di Spring MVC


118

Saya telah memperhatikan kode berikut mengarahkan Pengguna ke URL di dalam proyek,

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

sedangkan, berikut ini mengalihkan dengan benar seperti yang diinginkan, tetapi membutuhkan http: // atau 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;
    }

Saya ingin pengalihan untuk selalu mengarahkan ke URL yang ditentukan, apakah memiliki protokol yang valid di dalamnya atau tidak dan tidak ingin mengalihkan ke tampilan. Bagaimana saya bisa melakukan itu?

Terima kasih,

Jawaban:


208

Anda bisa melakukannya dengan dua cara.

Pertama:

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

Kedua:

@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
    return new ModelAndView("redirect:" + projectUrl);
}

19
Bahkan lebih sederhana jika Anda secara langsung mengembalikan String daripada ModelAndView.
daniel.eichten

24
Tampaknya dalam metode pertama Anda harus menyetel kode pengembalian ke 302. Jika tidak, server akan mengembalikan respons dengan kode 200 dan header Lokasi yang tidak menyebabkan pengalihan dalam kasus saya (Firefox 41.0).
Ivan Mushketyk

Bisakah kita juga menambahkan cookie saat mengarahkan ke URL Eksternal.
Srikar

1
Metode pertama membutuhkan@ResponseStatus(HttpStatus.FOUND)
lapkritinis

@Rinat Mukhamedgaliev Dalam ModelAndView ini ("redirect:" + projectUrl); Pernyataan apa yang akan menjadi kunci akan diambil sebagai default, jika yang ditambahkan adalah nilai?
JAVA

56

Anda dapat menggunakan RedirectView. Disalin dari JavaDoc :

Tampilan yang mengalihkan ke URL relatif, relatif konteks, atau permintaan saat ini

Contoh:

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

Anda juga dapat menggunakan ResponseEntity, mis

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

Dan tentu saja, kembali redirect:http://www.yahoo.comseperti yang disebutkan oleh orang lain.


RedirectView adalah satu-satunya yang tampaknya berhasil untuk saya!
Yakobus111

Saya mengalami perilaku stange dengan Tampilan Pengalihan, di webshpere saya mendapatkan: [kode] [27/04/17 13: 45: 55: 385 CDT] 00001303 aplikasi web E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E : [Error de servlet] - [DispatcherPrincipal]: java.io.IOException: pola tidak diizinkan di mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect (SecOutputFilter.java:234) di javax.servlet.http.HttpServletResponslet.http.HttpServletResponslet. sendRedirect (HttpServletResponseWrapper.java:145) [kode]
Carlos de Luna Saenz

49

Melihat implementasi sebenarnya dari UrlBasedViewResolver dan RedirectView , pengalihan akan selalu menjadi contextRelative jika target pengalihan Anda dimulai dengan /. Jadi, juga mengirimkan //yahoo.com/path/to/resource tidak akan membantu mendapatkan pengalihan relatif protokol.

Jadi untuk mencapai apa yang Anda coba, Anda dapat melakukan sesuatu seperti:

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

Tetapi dengan cara ini pengalihannya adalah GET atau tetap menjadi POST? Bagaimana cara mengalihkan sebagai POST?
Accollativo

Sebenarnya secara default ini mengembalikan 302 yang berarti harus mengeluarkan GET terhadap url yang disediakan. Untuk pengalihan dengan tetap menggunakan metode yang sama, Anda juga harus menyetel kode yang berbeda (307 pada HTTP / 1.1). Tetapi saya cukup yakin bahwa browser akan memblokir ini jika itu bertentangan dengan alamat absolut menggunakan kombinasi host / port yang berbeda karena masalah keamanan.
daniel.eichten

26

Cara lain untuk melakukannya adalah dengan menggunakan sendRedirectmetode ini:

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

22

Anda dapat melakukan ini dengan cara yang cukup ringkas menggunakan ResponseEntityseperti ini:

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

1
Ini harus menjadi jawaban yang diterima. Sangat mudah diatur dan digunakan.
cyberbit

9

Bagi saya bekerja dengan baik:

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

Saya pikir metode ini lebih baik daripada RedirectView karena bekerja di tukang pos juga.
mehdi mohammadi


3

Apakah Anda mencoba RedirectView di mana Anda bisa memberikan parameter contextRelative?


Parameter itu berguna untuk jalur yang dimulai (atau tidak) dengan /untuk memeriksa apakah harus relatif terhadap konteks webapp. Permintaan pengalihan akan tetap untuk host yang sama.
Sotirios Delimanolis

-2

Singkatnya "redirect://yahoo.com"akan meminjamkan Andayahoo.com .

dimana "redirect:yahoo.com"akan meminjamkanmu your-context/yahoo.comyaitu untuk mantanlocalhost:8080/yahoo.com


kedua solusi memiliki perintah yang sama: "Singkatnya" redirect: yahoo.com "vs" sedangkan "redirect: yahoo.com", dan hanya pengalihan url relatif yang bekerja.
partizanos
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.