Ответ 1
Насколько я знаю, эта проблема появляется только для pathvariable в конце requestmapping.
Мы смогли решить это, указав addge regex в requestmapping.
/somepath/{variable:.+}
Это продолжение вопроса Spring MVC @PathVariable получает усеченный
Spring forum утверждает, что он исправил (версия 3.2) как часть ContentNegotiationManager. см. ссылку ниже.
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632
В моем приложении requestParameter с .com усечен.
Может ли кто-нибудь объяснить мне, как использовать эту новую функцию? как он настраивается в xml?
Примечание:
Насколько я знаю, эта проблема появляется только для pathvariable в конце requestmapping.
Мы смогли решить это, указав addge regex в requestmapping.
/somepath/{variable:.+}
Spring считает, что все, что находится за последней точкой, является расширением файла, таким как .json
или .xml
, и проведите его, чтобы получить свой параметр.
Итак, если у вас есть /somepath/{variable}
:
/somepath/param
, /somepath/param.json
, /somepath/param.xml
или /somepath/param.anything
приведет к параметру со значением param
/somepath/param.value.json
, /somepath/param.value.xml
или /somepath/param.value.anything
приведет к параметру со значением param.value
если вы измените свое сопоставление на /somepath/{variable:.+}
, как было предложено, любая точка, включая последнюю, будет рассматриваться как часть вашего параметра:
/somepath/param
приведет к параметру со значением param
/somepath/param.json
приведет к параметру со значением param.json
/somepath/param.xml
приведет к параметру со значением param.xml
/somepath/param.anything
приведет к параметру со значением param.anything
/somepath/param.value.json
приведет к параметру со значением param.value.json
Если вы не любите распознавание расширений, вы можете отключить его, переопределив 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>
Итак, если у вас есть /somepath/{variable}
:
/somepath/param
, /somepath/param.json
, /somepath/param.xml
или /somepath/param.anything
приведет к параметру со значением param
/somepath/param.value.json
, /somepath/param.value.xml
или /somepath/param.value.anything
приведет к параметру со значением param.value
Примечание: отличие от конфигурации по умолчанию отображается только в том случае, если у вас есть сопоставление, например somepath/something.{variable}
. см. Задача проекта Resthub
если вы хотите сохранить управление расширением, так как Spring 3.2 вы также можете установить свойство useRegisteredSuffixPatternMatch для RequestMappingHandlerMapping bean, чтобы поддерживать распознавание suffixPattern, но ограничивается зарегистрированным расширением.
Здесь вы определяете только расширения json и 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>
Обратите внимание, что mvc: annotation-driven теперь принимает параметр contentNegotiation для предоставления пользовательского bean, но свойство RequestMappingHandlerMapping должно быть изменено на true (по умолчанию false) (cf. https://jira.springsource.org/browse/SPR-7632).
По этой причине вам все равно придется переопределить всю конфигурацию mvc: annotation. Я открыл билет на Spring, чтобы запросить пользовательскую RequestMappingHandlerMapping: https://jira.springsource.org/browse/SPR-11253. Пожалуйста, проголосуйте, если вы заняты.
В то время как переопределить, нужно подумать о том, чтобы переопределить обычное управление выполнением. В противном случае все ваши пользовательские сопоставления исключений не удастся. Вам придется повторно использовать messageCoverters со списком bean:
<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>
Я реализовал в проекте с открытым исходным кодом Resthub, что я являюсь частью набора тестов по этим темам: см. https://github.com/resthub/resthub-spring-stack/pull/219/files и https://github.com/resthub/resthub-spring-stack/issues/217
В дополнение к ответу Мартина Фрея это также можно устранить, добавив конечную косую черту в значение RequestMapping:
/path/{variable}/
Имейте в виду, что это исправление не поддерживает ремонтопригодность. Теперь требуется, чтобы весь URI имел завершающую косую черту - что-то, что может быть неясно для пользователей API/новых разработчиков. Поскольку, вероятно, не все параметры могут иметь .
в них, это может также создавать прерывистые ошибки
Обновление для Spring 4: начиная с 4.0.1 вы можете использовать PathMatchConfigurer
(через WebMvcConfigurer
), например
@Configuration
protected static class AllResources extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer matcher) {
matcher.setUseRegisteredSuffixPatternMatch(true);
}
}
В xml это будет (https://jira.spring.io/browse/SPR-10163):
<mvc:annotation-driven>
[...]
<mvc:path-matching registered-suffixes-only="true"/>
</mvc:annotation-driven>
добавление ":. +" работало для меня, но только после того, как я удалил внешние фигурные скобки.
value = { "/имя пользователя /{id:. +}" } не работает
value = "/username/{id:.+}" работает
Надеюсь, я помог кому-то:)
/somepath/{variable:.+}
работает в теге Java requestMapping
.
Здесь подход, основанный исключительно на 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;
}
}
Один довольно простой способ обойти эту проблему - добавить конечную косую черту...
например:.
использовать:
/somepath/filename.jpg/
вместо:
/somepath/filename.jpg
Полное решение, включающее адреса электронной почты в именах путей для spring 4.2,
<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>
Добавьте это в application-xml
Если вы используете Spring 3.2.x и <mvc:annotation-driven />
, создайте этот маленький 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;
}
}
Затем поместите это в свой конфигурационный файл MVC xml:
<bean class="spring.DoNotTruncateMyUrls" />
В Spring Boot, я разрешил их, выполнив следующие шаги: RestController:
@GetMapping("/statusByEmail/{email:.+}")
public List<Map<String, Object>> statusByEmail(@PathVariable(value = "email") String email)
И от клиента отдыха:
Get http://webhook.gsikder.com/statusByEmail/[email protected]/
В Spring Boot, выражение Regular решает проблему, например
@GetMapping("/path/{param1:.+}")