Перенаправление на внешний 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.
— Srikar 09

1
Первый метод требует@ResponseStatus(HttpStatus.FOUND)
— лапкритинис 09

@ Ринат Мухамедгалиев В этом ModelAndView ("перенаправление:" + projectUrl); Утверждение, какой ключ будет принят по умолчанию, если добавленная вещь является ценностью?
— JAVA

57

Вы можете использовать расширение 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

У меня странное поведение с представлением перенаправления, на webshpere я получаю: [код] [27.04.17 13:45: 55: 385 CDT] 00001303 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E : [Ошибка в сервлете] - [DispatcherPrincipal]: java.io.IOException: шаблон не разрешен в mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect (SecOutputFilter.java:234) в javax.servlet.httvrapper.Http sendRedirect (HttpServletResponseWrapper.java:145) [code]
— Карлос де Луна Саенс,

49

Если посмотреть на фактическую реализацию UrlBasedViewResolver и RedirectView, перенаправление всегда будет contextRelative, если ваша цель перенаправления начинается с /. Таким образом, отправка //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 01

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

26

Другой способ сделать это - просто использовать sendRedirectметод:

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

23

Вы можете сделать это довольно кратко, используя 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, так как он работает и в почтальоне.
— Мехди Мохаммади

8

Для внешнего URL-адреса вы должны использовать « http://www.yahoo.com » в качестве URL-адреса перенаправления.

Это объясняется в префиксе redirect: справочной документации Spring.

переадресовать: / MyApp / некоторые / ресурс

будет перенаправлять относительно текущего контекста сервлета, в то время как имя, такое как

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

перенаправит на абсолютный URL


3

Вы пробовали RedirectView, где можно указать параметр contextRelative?


Этот параметр полезен для путей, которые начинаются (или не начинаются), /чтобы проверить, должен ли он относиться к контексту веб-приложения. Запрос на перенаправление по-прежнему будет для того же хоста.
— Сотириос Делиманолис

-2

Короче "redirect://yahoo.com"одолжу тебеyahoo.com .

где как "redirect:yahoo.com"одолжит то your-context/yahoo.comесть за экс-localhost:8080/yahoo.com


в обоих решениях используется одна и та же команда: «Короче» redirect: yahoo.com «vs», где «redirect: yahoo.com», и работает только относительное перенаправление URL.
— partizanos
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.