Cách tốt nhất để lấy URL hiện tại trong Spring MVC là gì?


95

Tôi muốn tạo URL dựa trên URL được khách hàng sử dụng cho yêu cầu đang hoạt động. Có điều gì thông minh hơn việc lấy HttpServletRequestđối tượng hiện tại và đó là getParameter...()các phương pháp để xây dựng lại URL hoàn chỉnh bao gồm (và duy nhất) nó là tham số GET.

Làm rõ: Nếu có thể, tôi muốn từ bỏ việc sử dụng một HttpServletRequestđối tượng.

Câu trả lời:


111

Có hai phương pháp để truy cập dữ liệu này dễ dàng hơn, nhưng giao diện không cung cấp khả năng lấy toàn bộ URL bằng một lần gọi. Bạn phải xây dựng nó theo cách thủ công:

public static String makeUrl(HttpServletRequest request)
{
    return request.getRequestURL().toString() + "?" + request.getQueryString();
}

Tôi không biết về cách thực hiện việc này với bất kỳ cơ sở Spring MVC nào.

Nếu bạn muốn truy cập Yêu cầu hiện tại mà không chuyển nó đến mọi nơi, bạn sẽ phải thêm trình lắng nghe trong web.xml:

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

Và sau đó sử dụng điều này để nhận yêu cầu liên kết với Chủ đề hiện tại:

((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()

Ok, đây là một cách tiếp cận tương tự như những gì tôi đã làm cho đến nay. Nhưng tôi đang tìm kiếm một cách để làm điều này mà không thực sự sử dụng HttpServletRequestđối tượng. Điều này là do tôi đang sử dụng một số lớp / phương thức trợ giúp và tôi không muốn chuyển đối tượng yêu cầu mỗi lần.
Koraktor 29/09/09

Ok, tôi biết ý bạn và đã thêm thông tin bạn cần để truy cập yêu cầu hiện tại mà không cần chuyển nó.
Daff 29/09/09

Cảm ơn đã nhắc nhở về người nghe. Tôi vẫn chưa quen với Spring (và phát triển web Java nói chung). Tôi hiện đang sử dụng mã của bạn kết hợp với Spring Security's UrlUtils. Hoạt động như một sự quyến rũ.
Koraktor 29/09/09

Trong trường hợp của tôi, nó cung cấp đường dẫn chế độ xem liên quan thay vì duyệt url. Bất kỳ ý tưởng về điều này?
Md. Shougat Hossain

76

Thay vì sử dụng RequestContextHoldertrực tiếp, bạn cũng có thể sử dụng ServletUriComponentsBuildervà các phương thức tĩnh của nó:

  • ServletUriComponentsBuilder.fromCurrentContextPath()
  • ServletUriComponentsBuilder.fromCurrentServletMapping()
  • ServletUriComponentsBuilder.fromCurrentRequestUri()
  • ServletUriComponentsBuilder.fromCurrentRequest()

Chúng sử dụng ẩn RequestContextHolder, nhưng cung cấp thêm tính linh hoạt để tạo URL mới bằng cách sử dụng các khả năng của UriComponentsBuilder.

Thí dụ:

ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();
builder.scheme("https");
builder.replaceQueryParam("someBoolean", false);
URI newUri = builder.build().toUri();

@ m4rtin Tôi đã trả lời câu hỏi của riêng mình và không muốn nhận công lao cho người ban đầu đã giúp tôi giải quyết vấn đề của mình.
Koraktor

2
Cũng tốt cho Spring 5. Tôi đã quản lý để lấy URL bên trong a ConstraintValidatorwith ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString();.
GuiRitter

16

Lớp URI của Java có thể giúp bạn thực hiện điều này:

public static String getCurrentUrl(HttpServletRequest request){
    URL url = new URL(request.getRequestURL().toString());
    String host  = url.getHost();
    String userInfo = url.getUserInfo();
    String scheme = url.getProtocol();
    String port = url.getPort();
    String path = request.getAttribute("javax.servlet.forward.request_uri");
    String query = request.getAttribute("javax.servlet.forward.query_string");

    URI uri = new URI(scheme,userInfo,host,port,path,query,null)
    return uri.toString();
}

nó chỉ cung cấp tên máy chủ
Vivex

8

trong tệp jsp:

request.getAttribute("javax.servlet.forward.request_uri")

3

Bạn cũng có thể thêm một UriComponentsBuildervào chữ ký phương thức của phương thức bộ điều khiển của bạn. Spring sẽ đưa vào một phiên bản của trình xây dựng được tạo từ yêu cầu hiện tại.

@GetMapping
public ResponseEntity<MyResponse> doSomething(UriComponentsBuilder uriComponentsBuilder) {
    URI someNewUriBasedOnCurrentRequest = uriComponentsBuilder
            .replacePath(null)
            .replaceQuery(null)
            .pathSegment("some", "new", "path")
            .build().toUri();
  //...
}

Sử dụng trình tạo, bạn có thể trực tiếp bắt đầu tạo URI dựa trên yêu cầu hiện tại, ví dụ như sửa đổi các đoạn đường dẫn.

Xem thêm UriComponentsBuilderMethodArgumentResolver


Lưu ý rằng nội dung được đưa vào UriComponentsBuilderkhông bao gồm các tham số đường dẫn và truy vấn của yêu cầu. Nếu bạn cần truy cập vào những hoặc sử dụng ServletUriComponentsBuilder.fromCurrentRequest()hoặc tiêm một thể hiện của HttpServletRequestvà sử dụngServletUriComponentsBuilder.fromRequest(request)
Martin Devillers

-1

Nếu bạn cần URL cho đến tên máy chủ chứ không phải đường dẫn, hãy sử dụng Common Lib của Apache StringUtilvà từ URL trích xuất chuỗi con cho đến indexOf thứ ba /.

public static String getURL(HttpServletRequest request){
   String fullURL = request.getRequestURL().toString();
   return fullURL.substring(0,StringUtils.ordinalIndexOf(fullURL, "/", 3)); 
}

Ví dụ: Nếu fullurlhttps://example.com/path/after/url/sau đó đầu ra sẽ là https://example.com

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.