Làm cách nào để lấy URL miền và tên ứng dụng?


98

Đây là tình huống.

Ứng dụng web Java của tôi có đường dẫn sau

https://www.mywebsite.com:9443/MyWebApp

Giả sử có một tệp JSP

https://www.mywebsite.com:9443/MyWebApp/protected/index.jsp

và tôi cần lấy

https://www.mywebsite.com:9443/MyWebApp 

trong tệp JSP này.

Tất nhiên, có một cách khá lười biếng và ngớ ngẩn là chỉ lấy URL và sau đó dò lại đường dẫn trở lại.

Nhưng có một cách lập trình để làm điều này? Cụ thể, tôi nghĩ rằng tôi có thể lấy tên miền + cổng, nhưng làm cách nào để thực sự truy xuất tên ứng dụng "MyWebApp"?

Câu trả lời:


91

Tên ứng dụng web (thực ra là đường dẫn ngữ cảnh) có sẵn bằng cách gọi HttpServletrequest#getContextPath()(và do đó KHÔNG phải getServletPath()như một đề xuất trước đây). Bạn có thể lấy nó trong JSP bằng cách ${pageContext.request.contextPath}.

<p>The context path is: ${pageContext.request.contextPath}.</p>

Nếu bạn định sử dụng điều này cho tất cả các đường dẫn tương đối trong trang JSP của mình (điều này sẽ làm cho câu hỏi này có ý nghĩa hơn), thì bạn có thể sử dụng <base>thẻ HTML :

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="url">${req.requestURL}</c:set>
<c:set var="uri" value="${req.requestURI}" />

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2204870</title>
        <base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/">
        <script src="js/global.js"></script>
        <link rel="stylesheet" href="css/global.css">
    </head>
    <body>
        <ul>
            <li><a href="home.jsp">Home</a></li>
            <li><a href="faq.jsp">FAQ</a></li>
            <li><a href="contact.jsp">Contact</a></li>
        </ul>
    </body>
</html>

Tất cả các liên kết trong trang sau đó sẽ tự động có liên quan với nhau <base>để bạn không cần sao chép đường dẫn ngữ cảnh ở khắp mọi nơi. Lưu ý rằng khi các liên kết tương đối bắt đầu bằng a /, thì chúng sẽ không còn tương đối với <base>nữa mà thay vào đó là tên miền gốc.


Doc cho biết, "Đường dẫn ngữ cảnh được trả về ServletContext.getContextPath() phải được coi là đường dẫn ngữ cảnh chính hoặc ưu tiên của ứng dụng". Đó là lý do tôi đưa câu này vào câu trả lời ban đầu của mình, sau khi nhận ra điều đó. Tôi đã không loại bỏ nỗ lực đầu tiên của mình, vì tôi muốn OP xem xét việc đọc qua các tài liệu và biết thêm một chút về các phương pháp liên quan. Tôi hy vọng bạn đang hiểu điểm của tôi.
Adeel Ansari

@ Giấm: Đối với tệp JSP, kết getServletPath()quả trả về /filename.jsp. OP đã không yêu cầu điều đó ở tất cả, đây chắc chắn không phải là cách để đi.
BalusC

Tôi chắc chắn sẽ sửa chữa trong bài đăng của mình, nhưng lần này tôi đang mong đợi phản hồi cho nhận xét của tôi, điều này hoàn toàn khác :).
Adeel Ansari

2
Trong XHTML DOCTYPE, bạn sẽ cần thêm ký tự '/' vào contextPath. <base href = "$ {pageContext.request.contextPath} /">
Basil Musa

Tại sao bạn không đóng <base>thẻ? Không nên đóng tất cả thẻ?
Fabiano Francesconi

106

Hãy xem tài liệu cho HttpServletRequest.
Để tạo URL trong ví dụ của bạn, bạn sẽ cần sử dụng:

  • getScheme()
  • getServerName()
  • getServerPort()
  • getContextPath()

Đây là một phương thức sẽ trả về ví dụ của bạn:

public static String getURLWithContextPath(HttpServletRequest request) {
   return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}

1
Làm thế nào để lấy ip trong trường hợp tên máy chủ là localhost?
Mahmoud Saleh

chỉ cần lưu ý nhanh, getScheme () không phải lúc nào cũng hoạt động với https, một số máy chủ có hành vi kỳ lạ và có thể luôn trả về http thay vì https. tôi nghĩ rằng tôi nên cho bạn biết. thử request.getRequestURL (). toString () và xoa bóp nếu bạn cần
K ''

1
@MahmoudSalehrequest.getLocalAddr()
hơi xanh vào

Sẽ rất tốt nếu bạn cũng hiển thị đầu ra ví dụ cho mỗi phương thức. Thật khó khăn khi khởi động và chạy một máy chủ web chỉ để kiểm tra kết quả đầu ra của mỗi máy chủ.
Jus12

1
getContextPath()trong phương thức không trả về bất cứ điều gì! Và getServerPort()chỉ trả về số có 2 chữ số, không phải số có 4 chữ số! Tôi có thể tận dụng một số trợ giúp về nó?
sam

22

Tên ứng dụng đến từ getContextPath.

Tôi tìm thấy đồ họa này từ Agile Software Craftsmanship HttpServletRequest Path Decoding sắp xếp tất cả các phương pháp khác nhau có sẵn:

nhập mô tả hình ảnh ở đây


1
Hình này hữu ích để trả lời nhiều câu hỏi. Tôi đã cố gắng sử dụng nó trong câu trả lời cho nhiều câu hỏi, nhưng tất cả chúng đều bị xóa: có một quy tắc chống lại việc sử dụng lại cùng một câu trả lời. Thật là xấu hổ. Lý thuyết là nếu bạn sử dụng cùng một câu trả lời, thì các câu hỏi phải giống nhau, và vì vậy bạn chỉ nên đánh dấu câu hỏi là trùng lặp. Nhưng đó không phải là thực tế. Có nhiều câu hỏi khác nhau có thể được trả lời với cùng một hình ảnh. Thật là nhỏ nhen khi thực hiện các quy tắc tùy tiện như vậy. Nếu BẠN thấy một câu hỏi được trả lời tốt nhất với hình ảnh này, hãy sử dụng nó.
AgilePro


4

Đoạn mã sau có thể hữu ích cho ứng dụng web sử dụng JavaScript.

var newURL = window.location.protocol + "//"  + window.location.host + "" + window.location.pathname;

newURL = newURL.substring(0,newURL.indexOf(""));

0

Nếu bạn đang được chuyển một url dưới dạng Chuỗi và muốn trích xuất gốc ngữ cảnh của ứng dụng đó, bạn có thể sử dụng regex này để giải nén nó. Nó sẽ hoạt động cho các url đầy đủ hoặc các url tương đối bắt đầu bằng gốc ngữ cảnh.

url.replaceAll("^(.*\\/\\/)?.*?\\/(.+?)\\/.*|\\/(.+)$", "$2$3")
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.