Spring MVC @PathVariable с точкой (.) Усекается

Spring MVC @PathVariable с точкой (.) Усекается

1. обзор

В этом коротком руководстве мы обсудим общую проблему при работе с Spring MVC -when using a Spring @PathVariable with a @RequestMapping to map the end of a request URI that contains a dot, we’ll end up with a partial value in our variable, truncated at the last dot.

В следующих разделах мы сосредоточимся на том, почему это происходит и как изменить это поведение.

Для введения в Spring MVC обратитесь кto this article.

2. Нежелательная весенняя помощь

Платформа вызывает это часто нежелательное поведение из-за способа интерпретации переменной пути.

В частности,Spring considers that anything behind the last dot is a file extension, например.json или.xml.

В результате он усекает значение для извлечения параметра.

Давайте посмотрим на пример использования переменных пути, а затем проанализируем результат с различными возможными значениями:

@RestController
public class CustomController {
    @GetMapping("/example/{firstValue}/{secondValue}")
    public void example(@PathVariable("firstValue") String firstValue,
      @PathVariable("secondValue") String secondValue) {
        // ...
    }
}

В приведенном выше примере давайте рассмотрим следующие запросы и оценим наши переменные:

  • URLexample/gallery/link приводит к оценке "галереи"firstValue = и "ссылки"secondValue =

  • при использовании URLexample/gallery.df/link.ar у нас будетfirstValue = «gallery.df» иsecondValue = «link»

  • с URLexample/gallery.df/link.com.ar наши переменные будут:firstValue = «gallery.df» иsecondValue = «link.com»

Как мы видим, первая переменная не изменяется, а вторая всегда усекается.

3. Решения

Один из способов устранить это неудобство -modify our @PathVariable definition by adding a regex mapping. При этом любая точка, включая последнюю, будет считаться частью нашего параметра:

@GetMapping("/example/{firstValue}/{secondValue:.+}")
public void example(
  @PathVariable("firstValue") String firstValue,
  @PathVariable("secondValue") String secondValue) {
    //...
}

Другой способ избежать этой проблемы -adding a slash at the end of our @PathVariable. Это закроет нашу вторую переменную, защищающую ее от поведения Spring по умолчанию:

@GetMapping("/example/{firstValue}/{secondValue}/")

Два приведенных выше решения применяются к изменяемому сопоставлению одного запроса.

Если мы хотим изменить поведение на глобальном уровне MVC, мы можем настроить конфигурацию Spring MVC, объявив наш собственный bean-компонентDefaultAnnotationHandlerMapping в контексте приложения иsetting its useDefaultSuffixPattern property to false: 

@Configuration
public class CustomWebConfiguration extends WebMvcConfigurationSupport {

    @Bean
    public RequestMappingHandlerMapping
      requestMappingHandlerMapping() {

        RequestMappingHandlerMapping handlerMapping
          = super.requestMappingHandlerMapping();
        handlerMapping.setUseSuffixPatternMatch(false);
        return handlerMapping;
    }
}

Мы должны помнить, что этот подход влияет на все URL.

Используя эти 3 варианта, мы получим тот же результат: при вызове переменнойexample/gallery.df/link.com.ar URL, oursecondValue будет вычислено значение «link.com.ar» , чего мы и хотим.

4. Заключение

В этой быстрой записи мы изучили различные способы решения типичной проблемы при работе с@PathVariable и@RequestMapping в Spring MVC и источник этой проблемы.

Как всегда, доступен полный исходный код примеровover on GitHub.