Spring MVC @PathVariable com um ponto (.) Fica truncado

Spring MVC @PathVariable com um ponto (.) Fica truncado

1. Visão geral

Neste breve tutorial, discutiremos um problema comum ao trabalhar com 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.

Nas próximas seções, vamos nos concentrar em por que isso acontece e como mudar esse comportamento.

Para uma introdução ao Spring MVC, consulteto this article.

2. Ajuda indesejada da primavera

A estrutura causa esse comportamento geralmente indesejado devido à maneira como interpreta a variável de caminho.

Especificamente,Spring considers that anything behind the last dot is a file extension como.json ou.xml.

Como resultado, ele trunca o valor para recuperar o parâmetro.

Vamos ver um exemplo do uso de variáveis ​​de caminho e, em seguida, analisar o resultado com diferentes valores possíveis:

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

Com o exemplo acima, vamos considerar as próximas solicitações e avaliar nossas variáveis:

  • o URLexample/gallery/link resulta na avaliação defirstValue = “galeria” esecondValue = “link”

  • ao usar o URLexample/gallery.df/link.ar, teremosfirstValue = “gallery.df” esecondValue = “link”

  • com o URLexample/gallery.df/link.com.ar, nossas variáveis ​​serão:firstValue = “gallery.df” esecondValue = “link.com”

Como podemos ver, a primeira variável não é afetada, mas a segunda está sempre truncada.

3. Soluções

Uma maneira de resolver esse inconveniente émodify our @PathVariable definition by adding a regex mapping. Assim, qualquer ponto, incluindo o último, será considerado parte do nosso parâmetro:

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

Outra maneira de evitar esse problema é poradding a slash at the end of our @PathVariable. Isso incluirá nossa segunda variável protegendo-a do comportamento padrão do Spring:

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

As duas soluções acima se aplicam a um único mapeamento de solicitação que estamos modificando.

Se quisermos alterar o comportamento em um nível MVC global, podemos personalizar a configuração Spring MVC declarando nosso próprio beanDefaultAnnotationHandlerMapping no contexto do aplicativo esetting its useDefaultSuffixPattern property to false: 

@Configuration
public class CustomWebConfiguration extends WebMvcConfigurationSupport {

    @Bean
    public RequestMappingHandlerMapping
      requestMappingHandlerMapping() {

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

Temos que lembrar que essa abordagem afeta todos os URLs.

Com essas 3 opções, obteremos o mesmo resultado: ao chamar a variávelexample/gallery.df/link.com.ar URL, oursecondValue será avaliada para “link.com.ar” , que é o que queremos.

4. Conclusão

Neste rápido artigo, exploramos diferentes maneiras de resolver um problema comum ao trabalhar com@PathVariable e@RequestMapping no Spring MVC e a origem deste problema.

Como sempre, o código-fonte completo dos exemplos está disponívelover on GitHub.