Який найкращий спосіб отримати поточну URL-адресу у Spring MVC?


95

Я хотів би створити URL-адреси на основі URL-адреси, використовуваної клієнтом для активного запиту. Чи є щось розумніше, ніж взяти поточний HttpServletRequestоб’єкт, і це getParameter...()методи відновлення повної URL-адреси, включаючи (і лише) це параметри GET.

Уточнення: Якщо можливо, я хочу відмовитись від використання HttpServletRequestоб’єкта.

Відповіді:


111

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

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

Я не знаю про спосіб зробити це з будь-якими засобами Spring MVC.

Якщо ви хочете отримати доступ до поточного запиту, не передаючи його скрізь, вам доведеться додати слухача в web.xml:

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

А потім використовуйте це, щоб отримати запит, прив’язаний до поточної теми:

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

Добре, це подібний підхід до того, що я робив до цього часу. Але я шукаю спосіб зробити це, фактично не використовуючи HttpServletRequestоб’єкт. Це тому, що я використовую кілька допоміжних класів / методів, і я не хочу передавати об'єкт запиту щоразу.
Koraktor

Добре, я знаю, що ви маєте на увазі, і додав інформацію, необхідну для доступу до поточного запиту, не передаючи його.
Дафф

Дякую за нагадування про слухача. Я все ще новачок у Spring (і веб-розробці Java загалом). Зараз я використовую ваш код у поєднанні з Spring Security UrlUtils. Працює як шарм.
Koraktor

У моєму випадку це дає пов'язаний шлях перегляду замість URL-адреси перегляду. Будь-яке уявлення про це?
Md. Shougat Hossain

76

Замість RequestContextHolderбезпосереднього використання ви також можете використовувати ServletUriComponentsBuilderі його статичні методи:

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

Вони використовують RequestContextHolderпід капотом, але забезпечують додаткову гнучкість для створення нових URL-адрес, використовуючи можливості UriComponentsBuilder.

Приклад:

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

@ m4rtin Я відповів на власне запитання і не хотів брати кредит за того, хто спочатку допоміг мені вирішити мою проблему.
Koraktor

2
Також добре для весни 5. Мені вдалося отримати URL всередині ConstraintValidatorз ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString();.
GuiRitter

16

Клас URI Java може допомогти вам у цьому:

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();
}

це лише ім'я хосту
vivex


3

Ви також можете додати a UriComponentsBuilderдо підпису методу вашого методу контролера. Spring буде вводити екземпляр конструктора, створений з поточного запиту.

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

За допомогою конструктора ви можете безпосередньо розпочати створення URI на основі поточного запиту, наприклад, змінити сегменти шляху.

Див. Також UriComponentsBuilderMethodArgumentResolver


Зверніть увагу, що введений UriComponentsBuilderне включає параметри шляху та запиту запиту. Якщо вам потрібен доступ до тих, хто використовує ServletUriComponentsBuilder.fromCurrentRequest()або вводить екземпляр HttpServletRequestта використовуєServletUriComponentsBuilder.fromRequest(request)
Martin

-1

Якщо вам потрібна URL-адреса до імені хоста, а не шляху, використовуйте Common Lib Apache StringUtil, а з URL-адреси витягніть підрядок до третього indexOf /.

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

Приклад: Якщо fullURL , https://example.com/path/after/url/тоді вихід буде https://example.com

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.