rest @responsebody - Spring MVC @PathVariable con punto(.)Se está truncando




responseentity example (13)

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

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


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

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:.+}

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>

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);
}

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.


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

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

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


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

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

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

Es necesario proporcionar un candidato para autowire. Eso significa que debe saberse que una instancia de PasswordHint brota de manera que pueda adivinar que debe hacer referencia a ella.

Proporcione al jefe de clase de PasswordHint y / o la definición de esa clase para obtener más ayuda.

Intenta cambiar el nombre de

PasswordHintAction action;

a

PasswordHintAction passwordHintAction;

para que coincida con la definición de frijol.





spring rest spring-mvc spring-annotations