Это продолжение вопроса Spring MVC @PathVariable становится усеченным
Весенний форум заявляет, что он исправил (версия 3.2) как часть ContentNegotiationManager. см. ссылку ниже
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632
В моем приложении requestParameter с .com усекается.
Может ли кто-нибудь объяснить мне, как использовать эту новую функцию? как это настраивается в XML?
Примечание: весенний форум - # 1 Spring MVC @PathVariable с точкой (.) Усекается
spring
rest
spring-mvc
spring-annotations
Канагавелу Сугамар
источник
источник
<!-- Spring Configuration needed to avoid URI using dots to be truncated --> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="useDefaultSuffixPattern" value="false" /> </bean>
{variable_name:regular_expression}
, поэтому здесь у нас есть переменная с именемvariable
, значение которой будет сопоставлено с помощью регулярного выражения.+
(где.
означает «любой символ» и+
означает «один или несколько раз»).variable
регулярно, Spring использует свои функции определения суффиксов и обрезает все после точки. Когда вы используете сопоставление с регулярным выражением, эти функции не используются - переменная сопоставляется только с предоставленным вами регулярным выражением."variable:.+"
не работает, когда в переменной больше одной точки. например, размещение электронных писем в конце спокойных путей, таких как/path/abc@server.com.au
. Контроллер даже не вызывается, но он работает, когда есть только одна точка/path/abc@server.com
. Любая идея, почему и / или обходной путь?Spring считает, что все, что находится за последней точкой, является расширением файла, например,
.json
или,.xml
и используют его для получения вашего параметра.Так что если у вас есть
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Или/somepath/param.anything
приведет к парам со значениемparam
/somepath/param.value.json
,/somepath/param.value.xml
или/somepath/param.value.anything
приведет к параметру со значениемparam.value
если вы измените свое отображение на
/somepath/{variable:.+}
предложенное, любая точка, включая последнюю, будет считаться частью вашего параметра:/somepath/param
приведет к параметру со значениемparam
/somepath/param.json
приведет к параметру со значениемparam.json
/somepath/param.xml
приведет к параметру со значениемparam.xml
/somepath/param.anything
приведет к параметру со значениемparam.anything
/somepath/param.value.json
приведет к параметру со значениемparam.value.json
Если вас не волнует распознавание расширений, вы можете отключить его, переопределив
mvc:annotation-driven
automagic:Итак, еще раз, если у вас есть
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Или/somepath/param.anything
приведет к парам со значениемparam
/somepath/param.value.json
,/somepath/param.value.xml
или/somepath/param.value.anything
приведет к параметру со значениемparam.value
примечание: отличие от конфигурации по умолчанию видно только в том случае, если у вас есть подобное отображение
somepath/something.{variable}
. см. выпуск проекта Resthubесли вы хотите сохранить управление расширениями, начиная с Spring 3.2, вы также можете установить свойство useRegisteredSuffixPatternMatch компонента Bean RequestMappingHandlerMapping, чтобы сохранить активацию распознавания суффиксаPattern, но только для зарегистрированного расширения.
Здесь вы определяете только расширения json и xml:
Обратите внимание, что mvc: annotation-driven принимает теперь опцию contentNegotiation для предоставления пользовательского компонента, но свойство RequestMappingHandlerMapping должно быть изменено на true (по умолчанию false) (см. Https://jira.springsource.org/browse/SPR-7632 ).
По этой причине вам все равно придется переопределить всю конфигурацию, управляемую mvc: annotation. Я открыл билет в Spring, чтобы попросить пользовательский RequestMappingHandlerMapping: https://jira.springsource.org/browse/SPR-11253 . Пожалуйста, проголосуйте, если вы заинтересованы в.
При переопределении будьте внимательны, если учесть также переопределение управления выполнением. В противном случае все ваши пользовательские сопоставления исключений потерпят неудачу. Вам придется повторно использовать MessageCoverters с bean-компонентом списка:
Я реализовал в проекте с открытым исходным кодом Resthub , частью которого я являюсь, набор тестов по этим предметам: см. Https://github.com/resthub/resthub-spring-stack/pull/219/files & https: // github.com/resthub/resthub-spring-stack/issues/217
источник
Обновление для Spring 4: начиная с 4.0.1 вы можете использовать
PathMatchConfigurer
(через свойWebMvcConfigurer
), напримерВ xml это будет ( https://jira.spring.io/browse/SPR-10163 ):
источник
matcher.setUseSuffixPatternMatch(false)
для полного отключения совпадения суффиксов.В дополнение к ответу Мартина Фрея это также можно исправить, добавив косую черту в значение RequestMapping:
Имейте в виду, что это исправление не поддерживает ремонтопригодность. Теперь требуется, чтобы все URI имели косую черту - что может быть неочевидно для пользователей API / новых разработчиков. Поскольку, вероятно, не все параметры могут иметь
.
в них, это также может создавать периодические ошибкиисточник
В Spring Boot Rest Controller я решил эти проблемы следующим образом:
RestController:
И От Отдыха Клиента:
источник
добавление «:. +» работало на меня, но не до тех пор, пока я не удалил внешние фигурные скобки.
значение = { "/username/ndomid:.+}" } не работает
value = "/username/ndomid:.+}" работает
Надеюсь, я кому-то помог :)
источник
id
/somepath/{variable:.+}
работает вrequestMapping
теге Java .источник
"/{code:.+}"
работает для многих точек, а не для одного, т.е.61.12.7
он также работает для iek.a.p@o.i.n
Вот подход, основанный исключительно на конфигурации Java:
источник
Один из довольно простых способов обойти эту проблему - добавить косую черту ...
например:
использовать:
вместо:
источник
В Spring Boot, регулярное выражение решает проблему, как
источник
"/{code:.+}"
работает для многих точек, а не для одного, т.е.61.12.7
он также работает для iek.a.p@o.i.n
Полное решение, включающее адреса электронной почты в путевых именах для весны 4.2
Добавьте это в application-xml
источник
Если вы используете Spring 3.2.x и
<mvc:annotation-driven />
создайте это немногоBeanPostProcessor
:Затем поместите это в конфигурационный файл MVC xml:
источник
BeanPostProcessor
для этого. Если вы используете,WebMvcConfigurationSupport
вы можете переопределитьrequestMappingHandlerMapping
@Bean
метод. Если вы используете конфигурацию XML, вы можете просто объявить свой собственныйRequestMappingHandlerMapping
компонент и объявить это свойство.Наконец я нашел решение в Spring Docs :
Добавление этого к моей
WebMvcConfigurerAdapter
реализации решило проблему:источник
Для меня
работает, но только если вы также закодировали «точку» в URL-адресе запроса как «% 2E», тогда это работает. Но требует, чтобы все URL были такими ... которые не являются "стандартной" кодировкой, хотя допустимы. По ощущениям что-то вроде ошибки: |
Другой обходной путь, похожий на способ «косой черты», заключается в перемещении переменной, которая будет иметь точку «inline», например:
@GetMapping (path = "/ {variableName} / a")
теперь все точки будут сохранены, без изменений или регулярных выражений.
источник
Начиная с версии 5.2.4 (Spring Boot v2.2.6.RELEASE)
PathMatchConfigurer.setUseSuffixPatternMatch
иContentNegotiationConfigurer.favorPathExtension
устарели ( https://spring.io/blog/2020/03/24/spring-framework-5-2-5-available-now и https://github.com/spring-projects/spring-framework/issues/24179 ).Настоящая проблема заключается в том, что клиент запрашивает определенный тип мультимедиа (например, .com), а Spring добавляет все эти типы мультимедиа по умолчанию. В большинстве случаев ваш REST-контроллер будет генерировать только JSON, поэтому он не будет поддерживать запрошенный формат вывода (.com). Чтобы преодолеть эту проблему, у вас должно быть все в порядке, обновив свой контроллер покоя (или определенный метод), чтобы он поддерживал формат 'ouput' (
@RequestMapping(produces = MediaType.ALL_VALUE
)) и, конечно, разрешал такие символы, как точка ({username:.+}
).Пример:
Spring 5.3 и выше будут соответствовать только зарегистрированным суффиксам (типам носителей).
источник