Printemps MVC @PathVariable avec dot (.) se tronquée

c'est la suite de la question printemps MVC @PathVariable obtenir tronqué

Spring forum déclare 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 requestParameter with .com est tronqué.

quelqu'un Pourrait-il m'expliquer comment utiliser cette nouvelle fonctionnalité? comment est-il configurable au xml?

Note: forum du printemps- #1 Printemps MVC @PathVariable avec dot (.) devient tronqué

288
demandé sur Pragati Singh 2013-05-02 10:54:58
la source

13 ответов

autant Que je sache, ce problème n'apparaît que pour les pathvariable à la fin de la requestmapping.

nous avons pu résoudre cela en définissant l'addon regex dans le requestmapping.

 /somepath/{variable:.+}
403
répondu Martin Frey 2013-05-02 12:04:29
la source

Spring considère que tout ce qui se trouve derrière le dernier point est une extension de fichier telle que .json ou .xml et le transforme 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 résultera en un paramètre avec la valeur param
  • /somepath/param.value.json , /somepath/param.value.xml ou /somepath/param.value.anything résultera en un param avec valeur param.value

si vous changez votre mapping en /somepath/{variable:.+} comme suggéré, tout point, y compris le dernier sera considéré comme faisant partie de votre paramètre:

  • /somepath/param résultera en un paramètre avec la valeur param
  • /somepath/param.json résultera en un paramètre avec la valeur param.json
  • /somepath/param.xml résultera en un paramètre avec la valeur param.xml
  • /somepath/param.anything résultera en un paramètre avec la valeur param.anything
  • /somepath/param.value.json résultera en un paramètre avec la valeur param.value.json
  • ...

si vous ne vous souciez pas de la reconnaissance d'extension, vous pouvez la désactiver en remplaçant mvc:annotation-driven automagic:

<bean id="handlerMapping"
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
    <property name="useSuffixPatternMatch" value="false"/>
</bean>

donc, encore une fois, si vous avez /somepath/{variable} :

  • /somepath/param , /somepath/param.json , /somepath/param.xml ou /somepath/param.anything se traduira par un paramètre avec la valeur param
  • /somepath/param.value.json , /somepath/param.value.xml ou /somepath/param.value.anything résultera en un paramètre avec la valeur param.value

note : la différence par rapport à la configuration par défaut n'est visible que si vous avez une correspondance comme somepath/something.{variable} . voir numéro du projet Resthub "1519760920

si vous voulez garder la gestion d'extension, car Printemps 3.2 vous pouvez également définir la propriété useRegisteredSuffixPatternMatch de RequestMappingHandlerMapping bean afin de maintenir la reconnaissance de suffixPattern activée mais limitée à l'extension enregistrée.

ici vous définissez seulement les extensions JSON et xml:

<bean id="handlerMapping"
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
    <property name="useRegisteredSuffixPatternMatch" value="true"/>
</bean>

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false"/>
    <property name="favorParameter" value="true"/>
    <property name="mediaTypes">
        <value>
            json=application/json
            xml=application/xml
        </value>
    </property>
</bean>

noter que mvc: annotation-driven accepte maintenant une option contentNegotiation pour fournir un bean personnalisé, mais la propriété de RequestMappingHandlerMapping doit être changée en true (par défaut false) (cf. https://jira.springsource.org/browse/SPR-7632 ).

pour cette raison, vous devez toujours passer outre à la configuration MVC:annotation-driven. J'ai ouvert un billet pour Spring pour demander une demande personnaliséemappinghandlermapping: https://jira.springsource.org/browse/SPR-11253 . Votez s'il vous plaît si vous êtes interessé.

tout en dépassant, être prudent de considérer aussi coutume L'exécution de la gestion primordial. Sinon, tous vos mappages d'Exception personnalisés échoueront. Vous devrez réutiliser les décodeurs de messagerie avec un haricot de la liste:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />

<util:list id="messageConverters">
    <bean class="your.custom.message.converter.IfAny"></bean>
    <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</util:list>

<bean name="exceptionHandlerExceptionResolver"
      class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
    <property name="order" value="0"/>
    <property name="messageConverters" ref="messageConverters"/>
</bean>

<bean name="handlerAdapter"
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="conversionService" ref="conversionService" />
            <property name="validator" ref="validator" />
        </bean>
    </property>
    <property name="messageConverters" ref="messageConverters"/>
</bean>

<bean id="handlerMapping"
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
</bean>

j'ai mis en œuvre, dans le projet open source Resthub dont je fais partie, un ensemble d'essais sur ces sujets : Voir https://github.com/resthub/resthub-spring-stack/pull/219/files & https://github.com/resthub/resthub-spring-stack/issues/217

214
répondu bmeurant 2017-04-28 07:02:58
la source

mise à jour pour le printemps 4: depuis 4.0.1 vous pouvez utiliser PathMatchConfigurer (via votre WebMvcConfigurer ), par exemple

@Configuration
protected static class AllResources extends WebMvcConfigurerAdapter {

    @Override
    public void configurePathMatch(PathMatchConfigurer matcher) {
        matcher.setUseRegisteredSuffixPatternMatch(true);
    }

}

en xml, il serait ( https://jira.spring.io/browse/SPR-10163 ):

<mvc:annotation-driven>
    [...]
    <mvc:path-matching registered-suffixes-only="true"/>
</mvc:annotation-driven>
85
répondu Dave Syer 2014-08-08 13:15:50
la source

en plus de la réponse de Martin Frey, cela peut aussi être corrigé en ajoutant une barre oblique dans la valeur RequestMapping:

/path/{variable}/

gardez à l'esprit que ce correctif ne supporte pas la maintenabilité. Il faut maintenant que tous les URI aient une barre oblique-ce qui n'est peut-être pas évident pour les utilisateurs / nouveaux développeurs de L'API. Parce que ce n'est probablement pas tous les paramètres peuvent avoir un . en eux, il peut également créer des bogues intermittents

80
répondu Michał Rybak 2016-04-19 22:41:50
la source

ajouter ":.+ "a fonctionné pour moi, mais pas avant que j'ai enlevé les crochets bouclés extérieurs.

valeur = { "/nom d'utilisateur / {id:.+}" } n'a pas fonctionné

valeur = "/nom d'utilisateur/{id:.+}" œuvres

Hope I help someone :)

24
répondu Martin Čejka 2016-01-15 14:58:56
la source

dans le contrôleur Spring Boot Rest, j'ai résolu ces problèmes par les étapes suivantes:

RestController:

@GetMapping("/statusByEmail/{email:.+}/")
public String statusByEmail(@PathVariable(value = "email") String email){
  //code
}

Et Du Client De Repos:

Get http://mywebhook.com/statusByEmail/[email protected]/
18
répondu GoutamS 2018-01-17 19:52:09
la source

/somepath/{variable:.+} fonctionne en Java requestMapping tag.

14
répondu amit dahiya 2015-12-30 20:41:55
la source

Voici une approche qui repose uniquement sur la configuration java:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Configuration
public class MvcConfig extends WebMvcConfigurationSupport{

    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
        handlerMapping.setUseSuffixPatternMatch(false);
        handlerMapping.setUseTrailingSlashMatch(false);
        return handlerMapping;
    }
}
12
répondu Bruno Carrier 2016-05-14 13:56:13
la source

Une manière assez facile de contourner ce problème est d'ajouter une barre oblique ...

p.ex.:

utiliser:

/somepath/filename.jpg/

au lieu de:

/somepath/filename.jpg
9
répondu Marcelo C. 2015-10-07 20:50:04
la source

dans la botte de printemps, l'expression régulière résoudre le problème comme

@GetMapping("/path/{param1:.+}")
9
répondu Dan 2017-09-05 17:17:37
la source

la solution complète incluant les adresses e-mail dans les noms de chemins pour le printemps 4.2 est

<bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="true" />
    <property name="mediaTypes">
        <value>
            json=application/json
            xml=application/xml
        </value>
    </property>
</bean>
<mvc:annotation-driven
    content-negotiation-manager="contentNegotiationManager">
    <mvc:path-matching suffix-pattern="false" registered-suffixes-only="true" />
</mvc:annotation-driven>

ajouter à l'application-xml

6
répondu Paul Arer 2016-01-03 05:32:01
la source

si vous utilisez Spring 3.2.x et <mvc:annotation-driven /> , créez ce petit BeanPostProcessor :

package spring;

public final class DoNotTruncateMyUrls implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            ((RequestMappingHandlerMapping)bean).setUseSuffixPatternMatch(false);
        }
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

alors mettez ceci dans votre config MVC xml:

<bean class="spring.DoNotTruncateMyUrls" />
4
répondu Jukka 2013-05-29 22:38:16
la source

pour moi le

@GetMapping(path = "/a/{variableName:.+}")

ne fonctionne, mais seulement si vous encodez également le" point "dans l'url de votre requête comme" %2E " alors il fonctionne. Mais exige que les URL de tous...qui n'est pas un encodage "standard", bien que valide. Se sent comme quelque chose d'un bug :|

l'Autre Travail autour, similaire à la voie "slash arrière" est de déplacer la variable qui aura le point "inline" ex:

@GetMapping (path = " / {variableName} / a")

maintenant tous les points seront préservés, aucune modification ou regex est nécessaire.

0
répondu rogerdpack 2018-09-21 18:10:20
la source

Autres questions sur rest spring spring-mvc spring-annotations