Spring MVC @PathVariable avec un point (.) Est tronqué

Spring MVC @PathVariable avec un point (.) Est tronqué

1. Vue d'ensemble

Dans ce court didacticiel, nous aborderons un problème courant lors de l'utilisation de 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.

Dans les sections suivantes, nous allons nous concentrer sur les raisons pour lesquelles cela se produit et comment modifier ce comportement.

Pour une introduction à Spring MVC, veuillez vous référer àto this article.

2. Aide Spring indésirable

Le framework provoque ce comportement souvent indésirable en raison de la manière dont il interprète la variable de chemin.

Plus précisément,Spring considers that anything behind the last dot is a file extension comme.json ou.xml.

En conséquence, il tronque la valeur pour récupérer le paramètre.

Voyons un exemple d'utilisation de variables de chemin, puis analysons le résultat avec différentes valeurs possibles:

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

Avec l'exemple ci-dessus, examinons les prochaines demandes et évaluons nos variables:

  • l'URLexample/gallery/link aboutit à l'évaluation de la «galerie» defirstValue = et du «lien» desecondValue =

  • lors de l'utilisation de l'URL deexample/gallery.df/link.ar, nous auronsfirstValue = "gallery.df" etsecondValue = "link"

  • avec l'URL deexample/gallery.df/link.com.ar, nos variables seront:firstValue = "gallery.df" etsecondValue = "link.com"

Comme on peut le voir, la première variable n’est pas affectée mais la seconde est toujours tronquée.

3. Solutions

Une façon de résoudre cet inconvénient est demodify our @PathVariable definition by adding a regex mapping. Ainsi, tout point, y compris le dernier, sera considéré comme faisant partie de notre paramètre:

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

Une autre façon d'éviter ce problème est deadding a slash at the end of our @PathVariable. Cela englobera notre deuxième variable la protégeant du comportement par défaut de Spring:

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

Les deux solutions ci-dessus s'appliquent à un mappage de demande unique que nous modifions.

Si nous voulons changer le comportement à un niveau MVC global, nous pouvons personnaliser la configuration Spring MVC en déclarant notre propre beanDefaultAnnotationHandlerMapping dans le contexte de l'application etsetting its useDefaultSuffixPattern property to false: 

@Configuration
public class CustomWebConfiguration extends WebMvcConfigurationSupport {

    @Bean
    public RequestMappingHandlerMapping
      requestMappingHandlerMapping() {

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

Nous devons nous rappeler que cette approche affecte toutes les URL.

Avec ces 3 options, nous obtiendrons le même résultat: lors de l'appel de la variableexample/gallery.df/link.com.ar URL, oursecondValue sera évaluée à «link.com.ar» , c'est ce que nous voulons.

4. Conclusion

Dans cet article rapide, nous avons exploré différentes façons de résoudre un problème courant lorsque vous travaillez avec@PathVariable et@RequestMapping dans Spring MVC et la source de ce problème.

Comme toujours, le code source complet des exemples est disponibleover on GitHub.