Jak uzyskać adres URL domeny i nazwę aplikacji?

98

Oto scenariusz.

Moja aplikacja internetowa Java ma następującą ścieżkę

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

Powiedzmy, że istnieje plik JSP

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

i muszę odzyskać

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

w tym pliku JSP.

Oczywiście istnieje raczej leniwy i głupi sposób na po prostu pobranie adresu URL, a następnie ponowne śledzenie ścieżki z powrotem.

Ale czy jest na to programowy sposób? W szczególności wydaje mi się, że mogę uzyskać port domeny +, ale w jaki sposób mogę pobrać nazwę aplikacji „MyWebApp”?

ericbae
źródło

Odpowiedzi:

91

Nazwa aplikacji internetowej (a właściwie ścieżka kontekstu) jest dostępna przez wywołanie HttpServletrequest#getContextPath()(a zatem NIE getServletPath()taka, jak sugerowano wcześniej). Możesz pobrać to w JSP przez ${pageContext.request.contextPath}.

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

Jeśli zamierzasz użyć tego dla wszystkich ścieżek względnych na swojej stronie JSP (co miałoby sens w tym pytaniu), możesz skorzystać ze <base>znacznika 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>

Wszystkie linki na stronie będą wówczas automagicznie względne w stosunku do elementu, <base>dzięki czemu nie ma potrzeby kopiowania wszędzie ścieżki kontekstu. Zauważ, że kiedy linki względne zaczynają się od a /, to nie będą już względne względem <base>katalogu głównego domeny.

BalusC
źródło
Dokument stwierdza: „Ścieżka kontekstu zwrócona przez ServletContext.getContextPath() powinna być traktowana jako główna lub preferowana ścieżka kontekstu aplikacji”. To był powód, dla którego włączyłem to do mojej pierwotnej odpowiedzi, po uświadomieniu sobie tego. Nie usunąłem mojej pierwszej próby, ponieważ chcę, aby OP rozważył przeczytanie dokumentacji i dowiedzieć się trochę więcej o powiązanych metodach. Mam nadzieję, że rozumiesz mój punkt widzenia.
Adeel Ansari,
@Vinegar: w przypadku plików JSP getServletPath()zwraca /filename.jsp. OP wcale o to nie prosił, to z pewnością nie jest właściwa droga.
BalusC
Na pewno poprawiłbym swój post, ale tym razem spodziewałem się odpowiedzi na mój komentarz, która jest zupełnie inna :).
Adeel Ansari,
2
W XHTML DOCTYPE musisz dodać znak „/” do ścieżki contextPath. <base href = "$ {pageContext.request.contextPath} /">
Basil Musa
Dlaczego nie zamknąłeś <base>tagu? Czy wszystkie tagi nie powinny być zamknięte?
Fabiano Francesconi,
107

Zapoznaj się z dokumentacją dotyczącą HttpServletRequest.
Aby zbudować adres URL w swoim przykładzie, musisz użyć:

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

Oto metoda, która zwróci Twój przykład:

public static String getURLWithContextPath(HttpServletRequest request) {
   return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}
Jataro
źródło
1
jak uzyskać adres IP w przypadku, gdy nazwa serwera to localhost?
Mahmoud Saleh
uwaga, getScheme () nie zawsze działa dla https, niektóre serwery zachowują się dziwnie i zawsze mogą zwracać http zamiast https. Pomyślałem, że powinienem dać ci znać. spróbuj request.getRequestURL (). toString () i masuj, jeśli potrzebujesz
K ''
1
@MahmoudSalehrequest.getLocalAddr()
niebieskawe
Będzie dobrze, jeśli pokażesz również przykładowe dane wyjściowe dla każdej z metod. Uruchamianie serwera internetowego tylko po to, aby sprawdzić, jakie mogą być wyniki każdego z nich, jest uciążliwe.
Jus12
1
getContextPath()w metodzie nic nie zwraca! I getServerPort()zwraca tylko liczbę dwucyfrową, a nie czterocyfrową! Czy mógłbym skorzystać z pomocy?
sam
22

Nazwa aplikacji pochodzi od getContextPath.

Znajduję tę grafikę z Agile Software Craftsmanship HttpServletRequest Path Decoding sortuje wszystkie różne dostępne metody:

wprowadź opis obrazu tutaj

AgilePro
źródło
1
Ta grafika jest przydatna do odpowiedzi na wiele pytań. Próbowałem go użyć w odpowiedzi na wiele pytań, ale wszystkie zostały usunięte: obowiązuje zasada, że ​​nie wolno ponownie używać tej samej odpowiedzi. A szkoda. Teoria mówi, że jeśli użyjesz tej samej odpowiedzi, pytania muszą być takie same, dlatego powinieneś po prostu oznaczyć pytanie jako zduplikowane. Ale to nie jest rzeczywistość. Jest wiele różnych pytań, na które można odpowiedzieć za pomocą tej samej grafiki. Wdrażanie takich arbitralnych reguł jest małostkowe. Jeśli widzisz pytanie, na które najlepiej odpowiada ta grafika, użyj go.
AgilePro
4

Poniższy kod może być przydatny w przypadku aplikacji internetowych korzystających z JavaScript.

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

newURL = newURL.substring(0,newURL.indexOf(""));
Malutki
źródło
0

Jeśli adres URL jest przekazywany jako ciąg i chcesz wyodrębnić kontekstowy katalog główny tej aplikacji, możesz użyć tego wyrażenia regularnego, aby go wyodrębnić. Będzie działać dla pełnych lub względnych adresów URL, które zaczynają się od kontekstowego katalogu głównego.

url.replaceAll("^(.*\\/\\/)?.*?\\/(.+?)\\/.*|\\/(.+)$", "$2$3")
master_d
źródło