Аннотации типа в Python не предназначены для обеспечения соблюдения типа. Все, что связано с зависимостью статического типа во время выполнения, означало бы такие фундаментальные изменения, что даже бессмысленно продолжать называть результирующий язык «Python».
Обратите внимание, что динамическая природа Python делает ДОЛЖНЫ для создания внешний инструмент, используя код pure-python, для выполнения проверки типа времени выполнения. Это заставит программу работать (очень) медленно, но, возможно, она подходит для определенных категорий тестов.
Чтобы быть уверенным, одной из основ языка Python является то, что все является объектом, и что вы может попытаться выполнить любое действие над объектом во время выполнения. Если объект не имеет интерфейса, который соответствует выполненной попытке, он будет работать не во время выполнения.
Языки, которые по своей природе статически типизированы, работают по-другому: операции просто должны быть доступны на объектах при попытке во время выполнения. На этапе компиляции компилятор создает пробелы и слоты для соответствующих объектов повсюду - и при некорректной типизации разбивает компиляцию.
Проверка типов Python позволяет любому количеству инструментов точно выполнять что: прерывать и предупреждать на этапе до фактического запуска приложения (но независимо от самого компиляции). Но характер языка не может быть изменен, чтобы на самом деле требовать, чтобы объекты соответствовали во время выполнения - и очень важно печатать и разбивать на самом этапе компиляции.
Хотя, можно ожидать, что будущее версии Python могут включать в себя проверку типа времени компиляции в самой среде исполнения Python - скорее всего, через и необязательный ключ командной строки. (Я не думаю, что это когда-либо будет по умолчанию - по крайней мере, чтобы не сломать сборку - возможно, это может быть сделано по умолчанию для выдачи предупреждений)
Итак, Python не требует статической проверки типов во время выполнения, он перестанет быть Python. Но существует хотя бы один язык, который использует как динамические объекты, так и статическую типизацию - язык Cython, который на практике работает как супермножество Python. Следует ожидать, что Cython включит новый синтаксис типа-подсказки, который будет очень скоро объявлен. (В настоящее время он использует различный синтаксис для необязательных статически типизированных переменных)
Ну, есть два способа облегчения доступа к этим данным, но интерфейс не дает возможности получить весь 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();
Вы также можете добавить UriComponentsBuilder
к сигнатуре метода вашего контроллера. Spring добавит экземпляр создателя, созданного из текущего запроса.
@GetMapping
public ResponseEntity<MyResponse> doSomething(UriComponentsBuilder uriComponentsBuilder) {
URI someNewUriBasedOnCurrentRequest = uriComponentsBuilder
.replacePath(null)
.replaceQuery(null)
.pathSegment("some", "new", "path")
.build().toUri();
//...
}
Используя конструктор, вы можете сразу начать создавать URI на основе текущего запроса, например. изменить сегменты пути.
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();
}
Если вам нужен URL-адрес до имени хоста, а не путь, использующий общий доступ Apache StringUtil
, а из URL извлекайте подстроку до третьего индексаOF /
.
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
в файле jsp:
request.getAttribute("javax.servlet.forward.request_uri")
HttpServletRequest
. Это связано с тем, что я использую несколько вспомогательных классов / методов, и я не хочу каждый раз передавать объект запроса. – Koraktor 29 September 2009 в 08:41UrlUtils
. Работает как шарм. – Koraktor 29 September 2009 в 09:41