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