Chuyển hướng đến một URL bên ngoài từ hành động của trình điều khiển trong Spring MVC


118

Tôi đã nhận thấy đoạn mã sau đang chuyển hướng Người dùng đến một URL bên trong dự án,

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

ngược lại, phần sau đang chuyển hướng đúng như dự định nhưng yêu cầu http: // hoặc 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;
    }

Tôi muốn chuyển hướng luôn chuyển hướng đến URL được chỉ định, cho dù URL đó có giao thức hợp lệ trong đó hay không và không muốn chuyển hướng đến một chế độ xem. Làm thế nào tôi có thể làm điều đó?

Cảm ơn,

Câu trả lời:


208

Bạn có thể làm điều đó với hai cách.

Đầu tiên:

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

Thứ hai:

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

19
Nó thậm chí còn đơn giản hơn nếu bạn trực tiếp trả về một Chuỗi thay vì sau đó là ModelAndView.
daniel.eichten

24
Có vẻ như trong phương pháp đầu tiên, bạn nên đặt mã trả về thành 302. Nếu không, máy chủ sẽ trả về phản hồi có mã 200 và tiêu đề Vị trí không gây ra chuyển hướng trong trường hợp của tôi (Firefox 41.0).
Ivan Mushketyk

Chúng tôi cũng có thể thêm cookie trong quá trình chuyển hướng đến URL bên ngoài.
Srikar

1
Phương pháp đầu tiên yêu cầu@ResponseStatus(HttpStatus.FOUND)
lapkritinis

@Rinat Mukhamedgaliev Trong ModelAndView này ("redirect:" + projectUrl); Câu lệnh gì sẽ là khóa sẽ được coi là mặc định, nếu thứ được thêm vào là giá trị?
JAVA

56

Bạn có thể sử dụng RedirectView. Được sao chép từ JavaDoc :

Xem chuyển hướng đến URL liên quan tuyệt đối, ngữ cảnh hoặc yêu cầu hiện tại

Thí dụ:

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

Bạn cũng có thể sử dụng ResponseEntity, ví dụ:

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

Và tất nhiên, trở lại redirect:http://www.yahoo.comnhư đã đề cập bởi những người khác.


RedirectView là cái duy nhất có vẻ phù hợp với tôi!
James111,

Tôi đang gặp sự cố nghiêm trọng và Chế độ xem chuyển hướng wiwth của bạn, trên webshpere tôi nhận được: [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: mẫu không được phép tại mx.isban.security.components.SecOutputFilter $ WrapperRsSecured.sendRedirect (SecOutputFilter.java:234) tại javax.servlet.http.Httpesponsvlet.http.Http. sendRedirect (HttpServletResponseWrapper.java:145) [mã]
Carlos de Luna Saenz

49

Xem xét việc triển khai thực tế của UrlBasedViewResolverRedirectView , chuyển hướng sẽ luôn là contextRelative nếu mục tiêu chuyển hướng của bạn bắt đầu bằng /. Vì vậy, việc gửi //yahoo.com/path/to/resource cũng không giúp ích gì cho việc chuyển hướng giao thức tương đối.

Vì vậy, để đạt được những gì bạn đang cố gắng, bạn có thể làm điều gì đó như:

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

Nhưng theo cách này, chuyển hướng là GET hay vẫn là POST? Làm cách nào để chuyển hướng dưới dạng ĐĂNG?
Accollativo

Thực tế theo mặc định, điều này trả về 302 có nghĩa là nó sẽ phát hành GET đối với url được cung cấp. Để chuyển hướng giữ cùng một phương pháp, bạn cũng nên đặt một mã khác (307 kể từ HTTP / 1.1). Nhưng tôi khá chắc chắn rằng các trình duyệt sẽ chặn điều này nếu nó đi ngược lại một địa chỉ tuyệt đối bằng cách sử dụng kết hợp máy chủ / cổng khác do các vấn đề bảo mật.
daniel.eichten

26

Một cách khác để làm điều đó là sử dụng sendRedirectphương pháp:

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

22

Bạn có thể làm điều này theo cách khá ngắn gọn bằng cách sử dụng ResponseEntitynhư sau:

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

1
Đây phải là câu trả lời được chấp nhận. Cực kỳ dễ cài đặt và sử dụng.
cyberbit

9

Đối với tôi hoạt động tốt:

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

Tôi nghĩ rằng phương pháp này tốt hơn RedirectView vì nó cũng hoạt động trong người đưa thư.
mehdi mohammadi


3

Bạn đã thử RedirectView nơi bạn có thể cung cấp tham số contextRelative?


Tham số đó hữu ích cho các đường dẫn bắt đầu (hoặc không) với /để kiểm tra xem nó có liên quan đến ngữ cảnh ứng dụng web hay không. Yêu cầu chuyển hướng sẽ vẫn dành cho cùng một máy chủ.
Sotirios Delimanolis,

-2

Trong ngắn hạn "redirect://yahoo.com"sẽ cho bạn vay yahoo.com.

nơi "redirect:yahoo.com"sẽ cho bạn vay your-context/yahoo.comtức là cho ví dụlocalhost:8080/yahoo.com


cả hai giải pháp đều có cùng lệnh: "Trong ngắn hạn" redirect: yahoo.com "vs" trong đó là "redirect: yahoo.com" và chỉ chuyển hướng url tương đối đang hoạt động.
partizanos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.