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
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:.+}
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
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>
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
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 :)
In Spring Boot Rest Controller habe ich diese durch folgende Schritte gelöst:
@GetMapping("/statusByEmail/{email:.+}/")
public String statusByEmail(@PathVariable(value = "email") String email){
//code
}
Get http://mywebhook.com/statusByEmail/[email protected]/
/somepath/{variable:.+}
arbeitet im Java requestMapping
-Tag.
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;
}
}
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
In Spring Boot lösen die regulären Ausdrücke das Problem gerne
@GetMapping("/path/{param1:.+}")
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
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" />
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);
}
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.