Может ли конечная точка Spring RESTful узнать свой собственный шаблон URL '[duplicate]

Аннотации типа в Python не предназначены для обеспечения соблюдения типа. Все, что связано с зависимостью статического типа во время выполнения, означало бы такие фундаментальные изменения, что даже бессмысленно продолжать называть результирующий язык «Python».

Обратите внимание, что динамическая природа Python делает ДОЛЖНЫ для создания внешний инструмент, используя код pure-python, для выполнения проверки типа времени выполнения. Это заставит программу работать (очень) медленно, но, возможно, она подходит для определенных категорий тестов.

Чтобы быть уверенным, одной из основ языка Python является то, что все является объектом, и что вы может попытаться выполнить любое действие над объектом во время выполнения. Если объект не имеет интерфейса, который соответствует выполненной попытке, он будет работать не во время выполнения.

Языки, которые по своей природе статически типизированы, работают по-другому: операции просто должны быть доступны на объектах при попытке во время выполнения. На этапе компиляции компилятор создает пробелы и слоты для соответствующих объектов повсюду - и при некорректной типизации разбивает компиляцию.

Проверка типов Python позволяет любому количеству инструментов точно выполнять что: прерывать и предупреждать на этапе до фактического запуска приложения (но независимо от самого компиляции). Но характер языка не может быть изменен, чтобы на самом деле требовать, чтобы объекты соответствовали во время выполнения - и очень важно печатать и разбивать на самом этапе компиляции.

Хотя, можно ожидать, что будущее версии Python могут включать в себя проверку типа времени компиляции в самой среде исполнения Python - скорее всего, через и необязательный ключ командной строки. (Я не думаю, что это когда-либо будет по умолчанию - по крайней мере, чтобы не сломать сборку - возможно, это может быть сделано по умолчанию для выдачи предупреждений)

Итак, Python не требует статической проверки типов во время выполнения, он перестанет быть Python. Но существует хотя бы один язык, который использует как динамические объекты, так и статическую типизацию - язык Cython, который на практике работает как супермножество Python. Следует ожидать, что Cython включит новый синтаксис типа-подсказки, который будет очень скоро объявлен. (В настоящее время он использует различный синтаксис для необязательных статически типизированных переменных)

69
задан Koraktor 29 September 2009 в 08:35
поделиться

6 ответов

Ну, есть два способа облегчения доступа к этим данным, но интерфейс не дает возможности получить весь 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()
84
ответ дан Rasmus Faber 21 August 2018 в 05:40
поделиться
  • 1
    Хорошо, это аналогичный подход к тому, что я сделал до сих пор. Но я ищу способ сделать это без фактического использования объекта HttpServletRequest. Это связано с тем, что я использую несколько вспомогательных классов / методов, и я не хочу каждый раз передавать объект запроса. – Koraktor 29 September 2009 в 08:41
  • 2
    Хорошо, я знаю, что вы имеете в виду, и добавил информацию, необходимую для доступа к текущему запросу, не передавая ее. – Daff 29 September 2009 в 09:06
  • 3
    Спасибо за напоминание о слушателе. Я до сих пор не знаком с Spring (и Java-разработкой в ​​целом). Теперь я использую ваш код в сочетании с функцией Spring Security UrlUtils. Работает как шарм. – Koraktor 29 September 2009 в 09:41
  • 4
    В моем случае он дает связанный путь просмотра вместо URL-адреса просмотра. Есть идеи об этом? – Md. Shougat Hossain 5 August 2018 в 16:04

Вместо прямого использования 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();
39
ответ дан Koraktor 21 August 2018 в 05:40
поделиться
  • 1
    Спасибо, это был самый полезный ответ для меня. – John 25 April 2017 в 12:08
  • 2
    Должен быть принятый ответ с весны 3.1 – m4rtin 8 January 2018 в 11:48
  • 3
    @ m4rtin Я ответил на свой вопрос и не хотел брать кредит за того, кто изначально помог мне решить мою проблему. – Koraktor 8 January 2018 в 12:57
  • 4
    – GuiRitter 5 October 2018 в 14:34

Вы также можете добавить UriComponentsBuilder к сигнатуре метода вашего контроллера. Spring добавит экземпляр создателя, созданного из текущего запроса.

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

Используя конструктор, вы можете сразу начать создавать URI на основе текущего запроса, например. изменить сегменты пути.

См. также UriComponentsBuilderMethodArgumentResolver

1
ответ дан Mathias Dpunkt 21 August 2018 в 05:40
поделиться

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();
}
13
ответ дан René Vogt 21 August 2018 в 05:40
поделиться

Если вам нужен 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

0
ответ дан Sahil Chhabra 21 August 2018 в 05:40
поделиться

в файле jsp:

request.getAttribute("javax.servlet.forward.request_uri")
8
ответ дан Soner Gönül 21 August 2018 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: