Як отримати URL-адресу домену та ім’я програми?


98

Ось сценарій.

Мій веб-додаток Java має такий шлях

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

Скажімо, є файл JSP

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

і мені потрібно знайти

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

в цьому файлі JSP.

Звичайно, є досить ледачий і нерозумний спосіб просто отримати URL-адресу, а потім повторно простежити шлях назад.

Але чи існує програмний спосіб цього зробити? Зокрема, я думаю, що я можу отримати домен + порт, але як я можу фактично отримати ім'я програми "MyWebApp"?

Відповіді:


91

Назва веб-програми (фактично контекстний шлях) доступна за допомогою виклику HttpServletrequest#getContextPath()(і, отже, НЕ, getServletPath()як було запропоновано раніше). Ви можете отримати це в JSP за допомогою ${pageContext.request.contextPath}.

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

Якщо ви маєте намір використати це для всіх відносних шляхів на своїй сторінці JSP (це зробило б це питання більше сенсом), тоді ви можете скористатися <base>тегом 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>

Усі посилання на сторінці автоматично будуть відносно <base>таких, що вам не потрібно скрізь копіювати контурний шлях. Зауважте, що коли відносні посилання починаються з символу a /, вони вже не будуть відносні до <base>більше, а замість кореня домену.


Док заявляє: "Повернений шлях до контексту ServletContext.getContextPath() слід розглядати як основний або бажаний контекстний шлях програми". Це було причиною того, що я включив це до своєї оригінальної відповіді, усвідомивши річ. Я не видаляв свою першу спробу, оскільки хочу, щоб ОП розглядала читання через документи і знала трохи більше про пов'язані методи. Я сподіваюся, ви зрозумієте мою думку.
Адель Ансарі

@ Vinegar: для файлів JSP getServletPath()повертається /filename.jsp. ОП взагалі цього не просили, це точно не шлях.
BalusC

Я б, безумовно, вніс виправлення у своєму дописі, але цього разу я очікував відповіді на мій коментар, який зовсім інший :).
Адель Ансарі

2
У XHTML DOCTYPE вам потрібно буде додати символ "/" до contextPath. <base href = "$ {pageContext.request.contextPath} /">
Василь Муса

Чому ви не закрили <base>тег? Чи не слід закривати всі теги?
Fabiano Francesconi

106

Погляньте на документацію для HttpServletRequest.
Щоб створити URL-адресу у своєму прикладі, вам потрібно буде використовувати:

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

Ось метод, який поверне ваш приклад:

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

1
як отримати ip у випадку, якщо ім'я сервера було localhost?
Махмуд Салех

просто швидка примітка, getScheme () не завжди працює для https, деякі сервери мають дивну поведінку і завжди можуть повертати http замість https. Я думав, що я повинен дати вам знати. спробуйте request.getRequestURL (). toString () і масажуйте, якщо вам потрібно
K ''

1
@MahmoudSalehrequest.getLocalAddr()
синюватий

Буде добре, якщо ви також покажете приклад результату для кожного з методів. Болісно налаштувати і запустити веб-сервер, щоб перевірити, яким може бути вихід кожного з них.
Jus12

1
getContextPath()у методі нічого не повертає! І getServerPort()повертає лише двоцифрове число, а не чотиризначне число! Чи можу я скористатися якоюсь допомогою?
сам

22

Назва програми походить getContextPath.

Я знаходжу цю графіку від Agile Software Craftsmanship HttpServletRequest Path Decoding розбирає всі різні доступні методи:

введіть тут опис зображення


1
Ця графіка корисна для відповіді на багато питань. Я намагався використовувати його у відповіді на багато запитань, але всі вони були видалені: існує правило проти повторного використання тієї самої відповіді. Що соромно. Теорія полягає в тому, що якщо ви використовуєте ту саму відповідь, то питання повинні бути однаковими, і для цього слід просто позначити питання як дублікат. Але це не реальність. Є багато різних питань, на які можна відповісти з однаковою графікою. Реалізувати такі довільні правила малопомітно. Якщо ви бачите запитання, на яке найкраще відповідати в цій графіці, будь ласка, використовуйте його.
AgilePro


4

Наступний код може бути корисним для веб-додатків за допомогою JavaScript.

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

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

0

Якщо вам передається URL в якості рядка і хочете витягти контекстний корінь цієї програми, ви можете скористатися цим регулярним виразом для його вилучення. Він буде працювати для повних URL-адрес або відносних URL-адрес, які починаються з кореня контексту.

url.replaceAll("^(.*\\/\\/)?.*?\\/(.+?)\\/.*|\\/(.+)$", "$2$3")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.