Як отримати URI запиту без контекстного шляху?


127

Метод request.getRequestURI () повертає URI з контекстом.

Наприклад, якщо базовий URL з програми http://localhost:8080/myapp/(тобто контекст шлях MyApp ), і я закликаю request.getRequestURI()до http://localhost:8080/myapp/secure/users, він повернеться /myapp/secure/users.

Чи є якийсь спосіб ми можемо отримати лише цю частину /secure/users, тобто URI без контексту?


Відповіді:


158

Якщо ви знаходитесь у сервлеті переднього контролера, який відображається за схемою префікса, ви можете просто використовувати HttpServletRequest#getPathInfo().

String pathInfo = request.getPathInfo();
// ...

Якщо припустити, що сервлет у вашому прикладі відображений на карті /secure, то це повернеться, /usersщо було б інформацією, яка представляє єдиний інтерес усередині типового сервлета переднього контролера.

Якщо сервлет відображений на суфіксному шаблоні (однак у ваших прикладах URL-адреси не вказується, що це так) або коли ви фактично знаходитесь у фільтрі (коли сервлет, який потрібно викликати, ще не обов'язково визначається, getPathInfo()може повернутися null), тоді найкраще зробити підстановку URI запиту самостійно, виходячи з довжини контуру контексту, використовуючи звичайний Stringметод:

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...

Чи є причина використовувати це замість getServletPath()? Я пишу фільтр, і я помітив, що getPathInfo()повертається null, але getServletPath()повертає шлях мінус контексту (підходить для передачі диспетчеру запитів).
Джейсон C

@JasonC: Відповідно, getPathInfo()повертає нуль, якщо сервлет переднього контролера не відображається на шаблоні префікса.
BalusC

Так. Я мав на увазі: є причина, яку ви віддаєте перевагу getPathInfo над getServletPath? Багато інших високо оцінених відповідей тут також не використовують getServletPath, і саме це змушує мене підозріло ставитися до цього, і чому мені цікаво. У мене є проект сервлетів, над яким я працюю, і я намагаюся трохи відполірувати свої навички.
Джейсон C

1
@JasonC: шлях сервлетів може змінюватися, коли у вас встановлений MVC-сервер на базі сервлетів, наприклад JSF або Spring MVC. Тоді він буде представляти внутрішній шлях MVC фреймворку (наприклад, /foo.xhtmlзамість нього /foo.jsf), а не фактичний URI запиту (той, що вводиться як ендузер в адресному рядку браузера). Оригінальний шлях сервлета в такому випадку, однак, вирішується як атрибут запиту з ключем RequestDispatcher.FORWARD_SERVLET_PATH. У будь-якому випадку, питання явно запитує URI запиту (як в адресному рядку браузера), тому відповідь заснована саме на цьому.
BalusC

74
request.getRequestURI().substring(request.getContextPath().length())

Дивовижно! Це саме те, що я шукав.
майстер

4
+1 Я думаю, що це краща відповідь, ніж getPathInfo через те, що getPathInfo може бути недійсним та іншими дивацтвами. Різний Spring код отримує getContextPath і видаляє його з URI так само, як ви це зробили замість getPathInfo.
Адам Гент

32

З весною ви можете:

String path = new UrlPathHelper().getPathWithinApplication(request);

1
Звичайно, було б доцільно зберігати примірник UrlPathHelper, наприклад, як змінну для члена класу ...
Джеймс

Як ми можемо отримати URL-адресу відображення фактичного запиту? Будь ласка , керівництво тут: stackoverflow.com/questions/60446807 / ...
Pra_A

14

getPathInfo () іноді повертає null. У документації HttpServletRequest

Цей метод повертає null, якщо не було додаткової інформації про шлях.

Мені потрібно отримати шлях до файлу без контуру контексту у Filter та getPathInfo () повернути мені null. Тому я використовую інший метод: httpRequest.getServletPath ()

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String newPath = parsePathToFile(httpRequest.getServletPath());
    ...

}

8

Якщо ви використовуєте request.getPathInfo () всередині фільтра, вам завжди здається нульовим (принаймні, з пристані).

Цей короткий недійсний помилка + відповідь натякає на проблему, на яку я думаю:

https://isissue.apache.org/bugzilla/show_bug.cgi?id=28323

Я підозрюю, що це пов'язано з тим, що фільтри працюють до того, як сервлет отримає запит. Це може бути помилка в контейнері чи очікувана поведінка, яку я не зміг визначити.

Контекстний шлях доступний, однак рішення fforws працює навіть у фільтрах. Мені не подобається робити це вручну, але реалізація порушена або


5

Спосіб це зробити - відпочити шлях контексту серветки від URI запиту.

String p = request.getRequestURI();
String cp = getServletContext().getContextPath();

if (p.startsWith(cp)) {
  String.err.println(p.substring(cp.length());
}

Прочитайте тут .


-1

Можливо, ви можете просто скористатися методом розбиття, щоб усунути '/ myapp', наприклад:

string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];

3
Це спричинить проблему, якщо я розгортаю свою програму як root, а її базова URL-адреса стане localhost: 8080 . У цьому випадку request.getRequestURI () повернеться "/ secure / user", і ваш розділений метод викличе тут проблему. Код не повинен залежати від розгортання.
майстер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.