Перенаправлення на зовнішню URL-адресу від дії контролера у Spring MVC


118

Я помітив, що наступний код - це перенаправлення користувача до URL-адреси всередині проекту,

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

тоді як наступне перенаправлення належним чином за призначенням, але вимагає http: // або 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;
    }

Я хочу, щоб переадресація завжди переспрямовувалась на вказану URL-адресу, чи є у неї дійсний протокол чи ні, і не хочу перенаправляти на представлення. Як я можу це зробити?

Дякую,

Відповіді:


208

Зробити це можна двома способами.

Перший:

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

Друге:

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

19
Це ще простіше, якщо ви безпосередньо повертаєте String, а не ModelAndView.
daniel.eichten

24
Здається, що в першому методі слід встановити код повернення на 302. Інакше сервер поверне відповідь з кодом 200 та заголовком Location, що не викликає переспрямування в моєму випадку (Firefox 41.0).
Іван Мушкетик

Чи можемо ми також додати файли cookie під час переадресації до зовнішньої URL-адреси.
Шрікар

1
Перший метод вимагає@ResponseStatus(HttpStatus.FOUND)
lapkritinis

@Rinat Mukhamedgaliev У цьому ModelAndView ("переадресація:" + projectUrl); Заява про те, що було б ключовим, вважатиметься за замовчуванням, якщо доданою річчю є вартість?
JAVA

56

Ви можете використовувати RedirectView. Скопійовано з JavaDoc :

Перегляд, який переспрямовує на абсолютну, відносну до контексту чи поточну відносну URL-адресу запиту

Приклад:

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

Ви також можете використовувати ResponseEntity, наприклад,

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

І звичайно, повертайтеся, redirect:http://www.yahoo.comяк згадували інші.


RedirectView був єдиним, який, здавалося, працює для мене!
James111

Я маю поведінку під переглядом переадресації, в Інтернеті я отримую: [код] [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: шаблон не дозволений у mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect (SecOutputFilter.java:234) у javax.servlet.Servlet.http. sendRedirect (HttpServletResponseWrapper.java:145) [код]
Карлос де Луна Саенц

49

Переглядаючи фактичну реалізацію UrlBasedViewResolver і RedirectView, переспрямування завжди буде контекстним відносним, якщо ваша ціль переспрямування починається з /. Тому також надсилання //yahoo.com/path/to/resource не допоможе отримати відносне перенаправлення протоколу.

Отже, щоб досягти того, що ви намагаєтесь, ви можете зробити щось на кшталт:

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

Але таким чином переадресація є GET або це залишається POST? Як переадресувати як POST?
Accollativo

Насправді за замовчуванням це повернення 302, що означає, що він повинен видати GET проти наданої URL-адреси. Для перенаправлення, зберігаючи той самий метод, слід також встановити інший код (307, як у HTTP / 1.1). Але я впевнений, що браузери заблокують це, якщо це буде суперечити абсолютній адресі, використовуючи іншу комбінацію хост / порт через проблеми безпеки.
daniel.eichten

26

Ще один спосіб зробити це - просто скористатися sendRedirectметодом:

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

22

Це можна зробити досить стисло, використовуючи ResponseEntityтак:

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

1
Це має бути прийнятою відповіддю. Надзвичайно простий у налаштуванні та використанні.
Cyberbit

9

Для мене прекрасно працює:

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

Я думаю, що цей метод кращий, ніж RedirectView, оскільки він працює і в листоноші.
mehdi mohammadi

8

Для зовнішнього URL-адреси потрібно використовувати " http://www.yahoo.com " як URL-адресу переспрямування.

Це пояснюється у переспрямуванні: префікс весняної довідкової документації.

перенаправлення: / myapp / деякий / ресурс

буде перенаправляти відносно поточного контексту сервлета, тоді як ім'я, як

перенаправлення: http://myhost.com/some/arbitrary/path

перенаправить на абсолютну URL-адресу


3

Ви спробували RedirectView, де ви можете надати параметр контексту відносного?


Цей параметр корисний для шляхів, з яких починається (чи ні), /щоб перевірити, чи повинен він бути відповідним контексту webapp. Запит на переадресацію все ще буде для того самого хоста.
Sotirios Delimanolis

-2

Коротше кажучи "redirect://yahoo.com", позичу вам yahoo.com.

де як "redirect:yahoo.com"буде позичати вас, your-context/yahoo.comтобто для екс-localhost:8080/yahoo.com


обидва рішення мають однакову команду: "Коротше кажучи," переспрямування: yahoo.com "проти", де як "перенаправлення: yahoo.com", і працює лише відносне перенаправлення URL-адреси.
партизанос
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.