1. Обзор
В этом кратком руководстве мы обсудим распространенную проблему при работе с Spring MVC — при использовании Spring @PathVariable
с @RequestMapping
для сопоставления конца URI запроса, содержащего точку, мы получим частичное значение. в нашей переменной, усеченной до последней точки.
В следующих разделах мы сосредоточимся на том, почему это происходит и как изменить это поведение.
Введение в Spring MVC можно найти в этой статье .
2. Нежелательная помощь Spring
Фреймворк часто вызывает такое нежелательное поведение из-за того, как он интерпретирует переменную пути.
В частности, Spring считает, что все, что стоит за последней точкой, является расширением файла, таким как .json
или .xml.
В результате он усекает значение для получения параметра.
Давайте посмотрим на пример использования переменных пути, а затем проанализируем результат с различными возможными значениями:
@RestController
public class CustomController {
@GetMapping("/example/{firstValue}/{secondValue}")
public void example(@PathVariable("firstValue") String firstValue,
@PathVariable("secondValue") String secondValue) {
// ...
}
}
В приведенном выше примере давайте рассмотрим следующие запросы и оценим наши переменные:
- пример URL
/галерея/ссылка
приводит к оценкеfirstValue =
«gallery» иsecondValue =
«link» - при использовании URL-адреса
example/gallery.df/link.ar
у нас будетfirstValue
= «gallery.df» иsecondValue
= «link» - с URL-адресом
example/gallery.df/link.com.ar
наши переменные будут:firstValue
= «gallery.df» иsecondValue
= «link.com»
Как мы видим, первая переменная не затрагивается, но вторая всегда усекается.
3. Решения
Один из способов решить это неудобство — изменить наше определение @PathVariable
, добавив отображение регулярного выражения . Таким образом, любая точка, включая последнюю, будет считаться частью нашего параметра:
@GetMapping("/example/{firstValue}/{secondValue:.+}")
public void example(
@PathVariable("firstValue") String firstValue,
@PathVariable("secondValue") String secondValue) {
//...
}
Другой способ избежать этой проблемы — добавить косую черту в конце @PathVariable
. Это будет заключать в себя нашу вторую переменную, защищая ее от поведения Spring по умолчанию:
@GetMapping("/example/{firstValue}/{secondValue}/")
Два приведенных выше решения применяются к одному сопоставлению запросов, которое мы модифицируем.
Если мы хотим изменить поведение на глобальном уровне MVC, нам нужно предоставить пользовательскую конфигурацию . Для этой цели мы можем расширить WebMvcConfigurationSupport
и переопределить его метод getPathMatchConfigurer()
для настройки PathMatchConfigurer
.
@Configuration
public class CustomWebMvcConfigurationSupport extends WebMvcConfigurationSupport {
@Override
protected PathMatchConfigurer getPathMatchConfigurer() {
PathMatchConfigurer pathMatchConfigurer = super.getPathMatchConfigurer();
pathMatchConfigurer.setUseSuffixPatternMatch(false);
return pathMatchConfigurer;
}
}
Мы должны помнить, что этот подход влияет на все URL-адреса.
С этими тремя вариантами мы получим один и тот же результат: при вызове URL-адреса example/gallery.df/link.com.ar
наша переменная secondValue
будет оцениваться как «link.com.ar», что нам и нужно.
3.1. Уведомление об устаревании
Начиная с Spring Framework 5.2.4 метод setUseSuffixPatternMatch (boolean)
устарел, чтобы не поощрять использование расширений пути для маршрутизации запросов и согласования контента. По сути, текущая реализация затрудняет защиту веб-приложений от атаки отраженной загрузки файлов (RFD) .
Кроме того, начиная с Spring Framework 5.3, сопоставление шаблонов суффиксов будет работать только для явно зарегистрированных суффиксов, чтобы предотвратить произвольные расширения.
Суть в том, что с Spring 5.3 нам не нужно будет использовать setUseSuffixPatternMatch(false)
, так как он отключен по умолчанию.
4. Вывод
В этом кратком обзоре мы рассмотрели различные способы решения распространенной проблемы при работе с @PathVariable
и @RequestMapping
в Spring MVC и источник этой проблемы.
Как всегда, полный исходный код примеров доступен на GitHub .