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