it-swarm.com.de

Spring MVC @PathVariable mit Punkt (.) Wird abgeschnitten

Dies ist eine Fortsetzung von question Spring MVC @PathVariable wird abgeschnitten

Das Spring-Forum gibt an, dass es im ContentNegotiationManager behoben wurde (Version 3.2). siehe den Link unten.
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632

In meiner Anwendung wird requestParameter with .com abgeschnitten.

Könnte mir jemand erklären, wie man diese neue Funktion benutzt? Wie ist es bei XML konfigurierbar?

Hinweis: spring forum- # 1 Spring MVC @PathVariable mit Punkt (.) Wird abgeschnitten

311

Soweit ich weiß, tritt dieses Problem nur für die Pfadvariable am Ende des Requestmapping auf. 

Wir konnten das lösen, indem wir das Regex-Addon im Requestmapping definieren.

 /somepath/{variable:.+}
429
Martin Frey

Spring ist der Ansicht, dass alles hinter dem letzten Punkt eine Dateierweiterung wie .json oder .xml ist und diese zum Abrufen Ihres Parameters veranlasst.

Wenn Sie also /somepath/{variable} haben:

  • /somepath/param, /somepath/param.json, /somepath/param.xml oder /somepath/param.anything führt zu einem Parameter mit dem Wert param
  • /somepath/param.value.json, /somepath/param.value.xml oder /somepath/param.value.anything führt zu einem Parameter mit dem Wert param.value

wenn Sie Ihr Mapping wie vorgeschlagen in /somepath/{variable:.+} ändern, wird jeder Punkt einschließlich des letzten als Teil Ihres Parameters betrachtet:

  • /somepath/param führt zu einem Parameter mit dem Wert param
  • /somepath/param.json ergibt einen Parameter mit dem Wert param.json
  • /somepath/param.xml ergibt einen Parameter mit dem Wert param.xml 
  • /somepath/param.anything ergibt einen Parameter mit dem Wert param.anything
  • /somepath/param.value.json ergibt einen Parameter mit dem Wert param.value.json
  • ...

Wenn Sie sich nicht für die Erweiterungserkennung interessieren, können Sie sie deaktivieren, indem Sie mvc:annotation-driven automagic überschreiben:

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

Also wieder, wenn Sie /somepath/{variable} haben:

  • /somepath/param, /somepath/param.json, /somepath/param.xml oder /somepath/param.anything führt zu einem Parameter mit dem Wert param
  • /somepath/param.value.json, /somepath/param.value.xml oder /somepath/param.value.anything führt zu einem Parameter mit dem Wert param.value

hinweis: Der Unterschied zur Standardkonfiguration ist nur sichtbar, wenn Sie ein Mapping wie somepath/something.{variable} haben. siehe Resthub Projektproblem

wenn Sie die Erweiterungsverwaltung beibehalten möchten, können Sie seit Spring 3.2 auch die useRegisteredSuffixPatternMatch-Eigenschaft der RequestMappingHandlerMapping-Bean festlegen, um die SuffixPattern-Erkennung aktiviert zu lassen, jedoch auf die registrierte Erweiterung beschränkt.

Hier definieren Sie nur Json- und XML-Erweiterungen: 

<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>

Beachten Sie, dass mvc: annotation-driven jetzt eine contentNegotiation-Option zur Bereitstellung einer benutzerdefinierten Bean akzeptiert. Die Eigenschaft von RequestMappingHandlerMapping muss jedoch auf true (Standardwert false) geändert werden (siehe https://jira.springsource.org/browse/SPR -7632 ).

Aus diesem Grund müssen Sie immer noch die gesamte mvc: annotation-driven Konfiguration überschreiben. Ich habe ein Ticket für Spring geöffnet, um nach einem benutzerdefinierten RequestMappingHandlerMapping zu fragen: https://jira.springsource.org/browse/SPR-11253 . Bitte stimmen Sie ab, wenn Sie interaktiv sind.

Achten Sie beim Überschreiben auf das Überschreiben des benutzerdefinierten Ausführungsmanagements. Andernfalls schlagen alle Ihre benutzerdefinierten Ausnahmezuordnungen fehl. Sie müssen messageCoverters mit einem Listen-Bean wiederverwenden:

<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>

Ich habe im Open-Source-Projekt Resthub , an dem ich Mitglied bin, eine Reihe von Tests zu diesen Themen implementiert: siehe https://github.com/resthub/resthub-spring-stack/pull/219/ Dateien & https://github.com/resthub/resthub-spring-stack/issues/217

220
bmeurant

Update für Frühling 4: seit 4.0.1 können Sie PathMatchConfigurer (über Ihre WebMvcConfigurer) verwenden, z.

@Configuration
protected static class AllResources extends WebMvcConfigurerAdapter {

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

}

In XML wäre dies ( https://jira.spring.io/browse/SPR-10163 ):

<mvc:annotation-driven>
    [...]
    <mvc:path-matching registered-suffixes-only="true"/>
</mvc:annotation-driven>
89
Dave Syer

Neben der Antwort von Martin Frey kann dies auch durch Hinzufügen eines nachgestellten Schrägstrichs im RequestMapping-Wert behoben werden:

/path/{variable}/

Denken Sie daran, dass dieser Fix die Wartbarkeit nicht unterstützt. Jetzt müssen alle URIs einen nachgestellten Schrägstrich haben - etwas, das für API-Benutzer/neue Entwickler möglicherweise nicht erkennbar ist. Da wahrscheinlich nicht alle Parameter einen . enthalten, kann es auch zu zeitweiligen Fehlern kommen

83
Michał Rybak

das Hinzufügen des ":. +" funktionierte für mich, aber erst nachdem ich die äußeren geschweiften Klammern entfernt hatte.

value = {"/ Benutzername/{id:. +}"} hat nicht funktioniert

value = "/username/{id:.+}" works

Hoffe ich habe jemandem geholfen :)

25
Martin Čejka

In Spring Boot Rest Controller habe ich diese durch folgende Schritte gelöst:

RestController:

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

Und von Rest Client:

Get http://mywebhook.com/statusByEmail/[email protected]/
24
GoutamS

/somepath/{variable:.+} arbeitet im Java requestMapping-Tag.

14
amit dahiya

Hier ist ein Ansatz, der sich ausschließlich auf die Java-Konfiguration stützt:

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
Bruno Carrier

Eine ziemlich einfache Möglichkeit, dieses Problem zu umgehen, besteht darin, einen nachgestellten Schrägstrich anzufügen ...

z.B.:

benutzen :

/somepath/filename.jpg/

anstatt:

/somepath/filename.jpg
10
Marcelo C.

In Spring Boot lösen die regulären Ausdrücke das Problem gerne

@GetMapping("/path/{param1:.+}")
9
Dan

Die Komplettlösung mit E-Mail-Adressen in Pfadnamen für den Frühling 4.2 lautet 

<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>

Fügen Sie dies der application-xml hinzu

6
Paul Arer

Wenn Sie Spring 3.2.x und <mvc:annotation-driven /> verwenden, erstellen Sie diese kleine 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;
    }
}

Dann fügen Sie dies in Ihre MVC-Konfigurations-XML ein:

<bean class="spring.DoNotTruncateMyUrls" />
4
Jukka

Endlich fand ich eine Lösung in Spring Docs :

Um die Verwendung von Dateierweiterungen vollständig zu deaktivieren, müssen Sie Folgendes einstellen: 

 useSuffixPatternMatching(false), see PathMatchConfigurer

 favorPathExtension(false), see ContentNegotiationConfigurer

Das Hinzufügen zu meiner WebMvcConfigurerAdapter-Implementierung löste das Problem:

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(false);
}

@Override
public void configurePathMatch(PathMatchConfigurer matcher) {
    matcher.setUseSuffixPatternMatch(false);
}
1
luboskrnac

Für mich das 

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

funktioniert aber nur wenn Sie den "Punkt" in Ihrer Anfrage-URL auch als "% 2E" kodieren, dann funktioniert es. Aber es muss URLs für alle sein ..., die keine "Standard" -Codierung sind, obwohl sie gültig ist. Fühlt sich wie ein Fehler an: |

Die andere Problemumgehung, ähnlich wie beim "abschließenden Schrägstrich", besteht darin, die Variable mit dem Punkt "inline" ex zu verschieben:

@ GetMapping (Pfad = "/ {Variablenname}/a")

jetzt bleiben alle Punkte erhalten, es sind keine Änderungen oder Regex erforderlich.

0
rogerdpack