Ceci est la continuation de la question Spring MVC @PathVariable se tronquée
Le forum Spring indique qu'il a corrigé (version 3.2) dans le cadre de ContentNegotiationManager. voir le lien ci-dessous.
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632
Dans ma demande, le paramètre avec .com est tronqué.
Quelqu'un pourrait-il m'expliquer comment utiliser cette nouvelle fonctionnalité? comment est-il configurable au xml?
Remarque: Spring Forum - # 1 Spring MVC @PathVariable avec un point (.) Devient tronqué
la source
<!-- Spring Configuration needed to avoid URI using dots to be truncated --> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="useDefaultSuffixPattern" value="false" /> </bean>
{variable_name:regular_expression}
, nous avons donc ici une variable nomméevariable
, dont la valeur sera mise en correspondance en utilisant l'expression régulière.+
(où.
signifie «n'importe quel caractère» et+
signifie «une ou plusieurs fois»).variable
de manière régulière, Spring utilise ses fonctionnalités de détection de suffixe et tronque tout après le point. Lorsque vous utilisez la correspondance d'expressions régulières, ces fonctionnalités ne sont pas utilisées - la variable ne correspond qu'à l'expression régulière que vous fournissez."variable:.+"
ne fonctionne pas lorsqu'il y a plus d'un point dans la variable. par exemple, mettre des e-mails à la fin de chemins reposants comme/path/[email protected]
. Le contrôleur n'est même pas appelé, mais cela fonctionne quand il n'y a qu'un seul point/path/[email protected]
. Une idée pourquoi et / ou une solution de contournement?Spring considère que tout ce qui se trouve derrière le dernier point est une extension de fichier telle que
.json
or.xml
et la tronquer pour récupérer votre paramètre.Donc si vous avez
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Ou/somepath/param.anything
se traduira par une valeur avec paramparam
/somepath/param.value.json
,/somepath/param.value.xml
ou/somepath/param.value.anything
entraînera un paramètre avec une valeurparam.value
si vous modifiez votre mappage
/somepath/{variable:.+}
comme suggéré, tout point, y compris le dernier, sera considéré comme faisant partie de votre paramètre:/somepath/param
se traduira par un paramètre avec une valeurparam
/somepath/param.json
se traduira par un paramètre avec une valeurparam.json
/somepath/param.xml
se traduira par un paramètre avec une valeurparam.xml
/somepath/param.anything
se traduira par un paramètre avec une valeurparam.anything
/somepath/param.value.json
se traduira par un paramètre avec une valeurparam.value.json
Si vous ne vous souciez pas de la reconnaissance des extensions, vous pouvez la désactiver en
mvc:annotation-driven
remplaçant automagic:Donc, encore une fois, si vous avez
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Ou/somepath/param.anything
se traduira par une valeur avec paramparam
/somepath/param.value.json
,/somepath/param.value.xml
ou/somepath/param.value.anything
entraînera un paramètre avec une valeurparam.value
remarque: la différence avec la configuration par défaut n'est visible que si vous avez un mappage comme
somepath/something.{variable}
. voir problème du projet Resthubsi vous souhaitez conserver la gestion des extensions, depuis Spring 3.2, vous pouvez également définir la propriété useRegisteredSuffixPatternMatch du bean RequestMappingHandlerMapping afin de garder la reconnaissance suffixPattern activée mais limitée à l'extension enregistrée.
Ici, vous définissez uniquement les extensions json et xml:
Notez que mvc: annotation-driven accepte désormais une option contentNegotiation pour fournir un bean personnalisé mais la propriété de RequestMappingHandlerMapping doit être changée en true (false par défaut) (cf. https://jira.springsource.org/browse/SPR-7632 ).
Pour cette raison, vous devez toujours remplacer la configuration entièrement mvc: basée sur les annotations. J'ai ouvert un ticket pour Spring pour demander un RequestMappingHandlerMapping personnalisé: https://jira.springsource.org/browse/SPR-11253 . Veuillez voter si vous êtes intercepté.
Lors de la substitution, soyez prudent de considérer également la substitution de la gestion d'exécution personnalisée. Sinon, tous vos mappages d'exceptions personnalisés échoueront. Vous devrez réutiliser messageCoverters avec un bean list:
J'ai implémenté, dans le projet open source Resthub dont je fais partie, un ensemble de tests sur ces sujets: voir https://github.com/resthub/resthub-spring-stack/pull/219/files & https: // github.com/resthub/resthub-spring-stack/issues/217
la source
Mise à jour pour Spring 4: depuis 4.0.1, vous pouvez utiliser
PathMatchConfigurer
(via votreWebMvcConfigurer
), par exempleEn xml, ce serait ( https://jira.spring.io/browse/SPR-10163 ):
la source
matcher.setUseSuffixPatternMatch(false)
pour désactiver complètement la correspondance de suffixe.En plus de la réponse de Martin Frey, cela peut également être corrigé en ajoutant une barre oblique de fin dans la valeur RequestMapping:
N'oubliez pas que ce correctif ne prend pas en charge la maintenabilité. Il exige maintenant que tous les URI aient une barre oblique finale - quelque chose qui peut ne pas être apparent pour les utilisateurs d'API / les nouveaux développeurs. Comme il est probable que tous les paramètres ne contiennent pas de paramètre
.
, cela peut également créer des bogues intermittentsla source
Dans Spring Boot Rest Controller, j'ai résolu ces problèmes en suivant les étapes:
RestController:
Et depuis Rest Client:
la source
l'ajout du ":. +" a fonctionné pour moi, mais pas avant d'avoir supprimé les crochets extérieurs.
value = { "/username/{id:.+}" } n'a pas fonctionné
value = "/username/{id:.+}" fonctionne
J'espère que j'ai aidé quelqu'un :)
la source
id
/somepath/{variable:.+}
fonctionne enrequestMapping
balise Java .la source
"/{code:.+}"
fonctionne pour de nombreux points pas un, c'est-61.12.7
à- dire qu'il fonctionne également pour ie[email protected]
Voici une approche qui repose uniquement sur la configuration java:
la source
Un moyen assez simple de contourner ce problème consiste à ajouter une barre oblique de fin ...
par exemple:
utilisation :
au lieu de:
la source
Dans Spring Boot, l'expression régulière résout le problème comme
la source
"/{code:.+}"
fonctionne pour de nombreux points pas un, c'est-61.12.7
à- dire qu'il fonctionne également pour ie[email protected]
La solution complète incluant les adresses e-mail dans les noms de chemin pour le printemps 4.2 est
Ajoutez ceci à l'application-xml
la source
Si vous utilisez Spring 3.2.x et
<mvc:annotation-driven />
créez ce petitBeanPostProcessor
:Ensuite, mettez cela dans votre XML de configuration MVC:
la source
BeanPostProcessor
pour ça. Si vous utilisez,WebMvcConfigurationSupport
vous pouvez remplacer larequestMappingHandlerMapping
@Bean
méthode. Si vous utilisez la configuration XML, vous pouvez simplement déclarer votre propreRequestMappingHandlerMapping
bean et déclarer cette propriété.Enfin, j'ai trouvé une solution dans Spring Docs :
L'ajout de cela à mon
WebMvcConfigurerAdapter
implémentation a résolu le problème:la source
Pour moi le
fonctionne mais seulement si vous encodez également le "point" dans votre URL de demande en "% 2E" alors cela fonctionne. Mais les URL doivent être toutes ... ce qui n'est pas un encodage "standard", bien que valide. Se sent comme un bug: |
L'autre solution de contournement, similaire à la méthode "barre oblique de fin" consiste à déplacer la variable qui aura le point "en ligne" ex:
@GetMapping (path = "/ {variableName} / a")
maintenant tous les points seront conservés, aucune modification ou regex n'est nécessaire.
la source
Depuis Spring 5.2.4 (Spring Boot v2.2.6.RELEASE)
PathMatchConfigurer.setUseSuffixPatternMatch
etContentNegotiationConfigurer.favorPathExtension
sont obsolètes ( https://spring.io/blog/2020/03/24/spring-framework-5-2-5-available-now et https://github.com/spring-projects/spring-framework/issues/24179 ).Le vrai problème est que le client demande un type de média spécifique (comme .com) et Spring a ajouté tous ces types de média par défaut. Dans la plupart des cas, votre contrôleur REST ne produira que du JSON, il ne prendra donc pas en charge le format de sortie demandé (.com). Pour surmonter ce problème, vous devriez être tout à fait bien en mettant à jour votre contrôleur de repos (ou une méthode spécifique) pour prendre en charge le format 'ouput' (
@RequestMapping(produces = MediaType.ALL_VALUE
)) et bien sûr autoriser les caractères comme un point ({username:.+}
).Exemple:
Spring 5.3 et supérieur ne correspondront qu'aux suffixes enregistrés (types de support).
la source