responseentity responsebody requestmapping requestbody postmapping example ejemplo spring rest spring-mvc spring-annotations

responsebody - spring boot rest controller mapping



Spring MVC @PathVariable con punto(.) Se está truncando (14)

Actualización para Spring 4: desde la PathMatchConfigurer 4.0.1 puede usar PathMatchConfigurer (a través de su WebMvcConfigurer ), por ejemplo

@Configuration protected static class AllResources extends WebMvcConfigurerAdapter { @Override public void configurePathMatch(PathMatchConfigurer matcher) { matcher.setUseRegisteredSuffixPatternMatch(true); } }

En xml, sería ( https://jira.spring.io/browse/SPR-10163 ):

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

Esta es la continuación de la pregunta Spring MVC @PathVariable truncada

El foro de Spring indica que se ha corregido (versión 3.2) como parte de ContentNegotiationManager. Vea el siguiente enlace.
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632

En mi aplicación se trunca el parámetro de solicitud con .com.

¿Alguien podría explicarme cómo usar esta nueva característica? ¿Cómo es configurable en xml?

Nota: spring forum- # 1 Spring MVC @PathVariable con punto (.) Se está truncando


Además de la respuesta de Martin Frey, esto también puede solucionarse agregando una barra diagonal al valor de RequestMapping:

/path/{variable}/

Tenga en cuenta que esta solución no admite la capacidad de mantenimiento. Ahora se requiere que todos los URI tengan una barra inclinada, algo que puede no ser evidente para los usuarios de API / nuevos desarrolladores. Porque es probable que no todos los parámetros tengan un . En ellos, también puede crear errores intermitentes.


Aquí hay un enfoque que se basa únicamente en la configuración de 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; } }


En Spring Boot Rest Controller, he resuelto estos pasos siguiendo estos pasos:

RestController:

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

Y de Rest Client:

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


En Spring Boot, la expresión Regular resuelve el problema como

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


Finalmente encontré la solución en Spring Docs :

Para deshabilitar completamente el uso de las extensiones de archivo, debe configurar lo siguiente:

useSuffixPatternMatching(false), see PathMatchConfigurer favorPathExtension(false), see ContentNegotiationConfigurer

Agregar esto a mi implementación de WebMvcConfigurerAdapter solucionó el problema:

@Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorPathExtension(false); } @Override public void configurePathMatch(PathMatchConfigurer matcher) { matcher.setUseSuffixPatternMatch(false); }


La solución completa que incluye las direcciones de correo electrónico en los nombres de ruta para la primavera 4.2 es

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

Añade esto a la aplicación-xml


Para mi el

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

funciona, pero solo si también codifica el "punto" en su url de solicitud como "% 2E", entonces funciona. Pero requiere que las URL sean todas ... que no sean una codificación "estándar", aunque son válidas. Se siente como una especie de error: |

La otra alternativa, similar a la forma de "barra inclinada al final" es mover la variable que tendrá el punto "en línea" ej:

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

ahora se conservarán todos los puntos, no se necesitan modificaciones ni expresiones regulares.


Por lo que sé, este problema aparece solo para la variable de ruta al final del mapeo de solicitud.

Pudimos resolver eso definiendo el complemento de expresiones regulares en el mapeo de solicitud.

/somepath/{variable:.+}


Si está utilizando Spring 3.2.xy <mvc:annotation-driven /> , cree este pequeño 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; } }

Luego ponga esto en su configuración MVC xml:

<bean class="spring.DoNotTruncateMyUrls" />


Spring considera que cualquier cosa detrás del último punto es una extensión de archivo como .json o .xml y trucarla para recuperar su parámetro.

Así que si tienes /somepath/{variable} :

  • /somepath/param , /somepath/param.json , /somepath/param.xml o /somepath/param.anything resultará en un parámetro con valor param
  • /somepath/param.value.json , /somepath/param.value.xml o /somepath/param.value.anything resultará en un param.value con valor param.value

Si cambia su asignación a /somepath/{variable:.+} como se sugiere, cualquier punto, incluido el último, se considerará como parte de su parámetro:

  • /somepath/param dará como resultado un parámetro con valor param
  • /somepath/param.json dará como resultado un param.json con valor param.json
  • /somepath/param.xml resultará en un param.xml con valor param.xml
  • /somepath/param.anything resultará en un param.anything con valor param.anything
  • /somepath/param.value.json dará como resultado un param.value.json con valor param.value.json
  • ...

Si no le importa el reconocimiento de extensión, puede desactivarlo anulando 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>

Entonces, de nuevo, si tienes /somepath/{variable} :

  • /somepath/param , /somepath/param.json , /somepath/param.xml o /somepath/param.anything resultará en un parámetro con valor param
  • /somepath/param.value.json , /somepath/param.value.xml o /somepath/param.value.anything resultará en un param.value con valor param.value

nota: la diferencia con la configuración predeterminada es visible solo si tiene una asignación como somepath/something.{variable} . ver el tema del proyecto Resthub

Si desea mantener la administración de extensiones, desde Spring 3.2 también puede configurar la propiedad useRegisteredSuffixPatternMatch del bean RequestMappingHandlerMapping para mantener activado el reconocimiento suffixPattern pero limitado a la extensión registrada.

Aquí solo se definen las extensiones json y 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>

Tenga en cuenta que mvc: annotation-driven ahora acepta una opción contentNegotiation para proporcionar un bean personalizado, pero la propiedad de RequestMappingHandlerMapping debe cambiarse a verdadero (valor predeterminado falso) (consulte https://jira.springsource.org/browse/SPR-7632 ).

Por esa razón, todavía tiene que anular la configuración de mvc: annotation-impulsada por todos. Abrí un boleto a Spring para solicitar un RequestMappingHandlerMapping personalizado: https://jira.springsource.org/browse/SPR-11253 . Por favor vota si estás interesado.

Mientras reemplaza, tenga cuidado de considerar también la omisión de la administración de ejecución personalizada. De lo contrario, todas sus asignaciones de excepción personalizadas fallarán. Deberá reutilizar messageCoverters con un bean de lista:

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

Implementé, en el proyecto de código abierto Resthub que Resthub parte, un conjunto de pruebas sobre estos temas: consulte https://github.com/resthub/resthub-spring-stack/pull/219/files & https: // github.com/resthub/resthub-spring-stack/issues/217


Una forma bastante fácil de solucionar este problema es agregar una barra inclinada ...

p.ej:

utilizar :

/somepath/filename.jpg/

en lugar de:

/somepath/filename.jpg


agregar el ":. +" funcionó para mí, pero no hasta que quité los soportes externos.

value = { "/username/{id:.+}" } no funcionó

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

Espero haber ayudado a alguien :)


/somepath/{variable:.+} funciona en la etiqueta requestMapping Java.