Как лучше всего получить текущий URL-адрес в Spring MVC?
-
18-09-2019 - |
Вопрос
Я хотел бы создать URL-адреса на основе URL-адреса, используемого клиентом для активного запроса.Есть ли что-нибудь умнее, чем принять текущий HttpServletRequest
объект и это getParameter...()
методы для восстановления полного URL-адреса, включая (и только) его параметры GET.
Уточнение:Если возможно, я хочу отказаться от использования HttpServletRequest
объект.
Решение
Есть два способа упростить доступ к этим данным, но интерфейс не дает возможности получить весь 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()
Другие советы
Вместо использования 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();
Класс 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();
}
в jsp-файле:
request.getAttribute("javax.servlet.forward.request_uri")
Вы также можете добавить UriComponentsBuilder
к сигнатуре метода вашего метода контроллера.Spring внедрит экземпляр построителя, созданный на основе текущего запроса.
@GetMapping
public ResponseEntity<MyResponse> doSomething(UriComponentsBuilder uriComponentsBuilder) {
URI someNewUriBasedOnCurrentRequest = uriComponentsBuilder
.replacePath(null)
.replaceQuery(null)
.pathSegment("some", "new", "path")
.build().toUri();
//...
}
Используя конструктор, вы можете напрямую начать создавать URI на основе текущего запроса, например.изменить сегменты пути.
Смотрите также UriComponentsBuilderMethodArgumentResolver
Если вам нужен 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));
}
Пример: Если полныйURL является https://example.com/path/after/url/
затемВыход будет https://example.com