Spring MVC @PathVariable가 잘림 “/{blahName}”) public ModelAndView getBlah(@PathVariable

정보에 대한 RESTful 액세스를 제공하는 컨트롤러가 있습니다.

@RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}")
public ModelAndView getBlah(@PathVariable String blahName, HttpServletRequest request,
                            HttpServletResponse response) {

내가 겪고있는 문제는 특수 문자가있는 경로 변수로 서버를 치면 잘립니다. 예를 들면 다음과 같습니다.
http : // localhost : 8080 / blah-server / blah / get / blah2010.08.19-02 : 25 : 47

blahName 매개 변수는 blah2010.08입니다.

그러나 request.getRequestURI () 호출에는 전달 된 모든 정보가 포함됩니다.

Spring이 @PathVariable을 자르지 못하게하는 방법에 대한 아이디어가 있습니까?



답변

@RequestMapping인수에 대한 정규식을 시도하십시오 .

RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName:.+}")


답변

이것은 아마도 SPR-6164 와 밀접한 관련이 있습니다. 간단히 말해서 프레임 워크는 URI 해석에 스마트를 적용하여 파일 확장자라고 생각하는 것을 제거하려고합니다. 이것은 파일 확장자 라고 생각하기 때문에 blah2010.08.19-02:25:47로 바뀌는 효과가 있습니다.blah2010.08.19-02:25:47

연결된 문제에 설명 된대로 DefaultAnnotationHandlerMapping앱 컨텍스트에서 고유 한 Bean 을 선언 하고 해당 useDefaultSuffixPattern속성을로 설정 하여이 동작을 비활성화 할 수 있습니다 false. 이것은 기본 동작을 무시하고 데이터를 희롱하는 것을 중지합니다.


답변

봄의 마지막 점 뒤에 아무것도 같은 파일 확장자를 것을 고려 .json하거나 .xml당신의 매개 변수를 검색을 절단.

그래서 당신이 가지고 있다면 /{blahName}:

  • /param, /param.json, /param.xml또는 /param.anything값으로 될 것이다 PARAMparam
  • /param.value.json, /param.value.xml또는 /param.value.anything값으로 될 것이다 PARAMparam.value

매핑을 /{blahName:.+}제안대로 변경 하면 마지막 점을 포함한 점이 매개 변수의 일부로 간주됩니다.

  • /param 가치가있는 매개 변수가됩니다 param
  • /param.json 가치가있는 매개 변수가됩니다 param.json
  • /param.xml 가치가있는 매개 변수가됩니다 param.xml
  • /param.anything 가치가있는 매개 변수가됩니다 param.anything
  • /param.value.json 가치가있는 매개 변수가됩니다 param.value.json

확장 인식을 신경 쓰지 않으면 mvc:annotation-drivenautomagic 을 재정 의하여 확장 인식을 비활성화 할 수 있습니다 .

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

따라서 다시 한 번 /{blahName}:

  • /param, /param.json, /param.xml또는 /param.anything값으로 될 것이다 PARAMparam
  • /param.value.json, /param.value.xml또는 /param.value.anything값으로 될 것이다 PARAMparam.value

참고 : 기본 구성과의 차이점은와 같은 매핑이있는 경우에만 표시됩니다 /something.{blahName}. Resthub 프로젝트 문제를 참조하십시오 .

확장 관리를 유지하려면 Spring 3.2부터 suffixPattern 인식을 활성화하지만 등록 된 확장으로 제한하기 위해 RequestMappingHandlerMapping Bean의 useRegisteredSuffixPatternMatch 특성을 설정할 수도 있습니다.

여기에 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은 이제 customN을 제공하기 위해 contentNegotiation 옵션을 허용하지만 RequestMappingHandlerMapping의 특성을 true (기본값 false)로 변경해야합니다 ( https://jira.springsource.org/browse/SPR-7632). ).

이러한 이유로 여전히 모든 mvc : annotation-driven 구성을 대체해야합니다. 사용자 정의 RequestMappingHandlerMapping을 요청하기 위해 Spring 티켓을 열었습니다 ( 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/fileshttps : // 참조 github.com/resthub/resthub-spring-stack/issues/217


답변

마지막 점 뒤의 모든 것은 파일 확장자로 해석되며 기본적으로 잘립니다.
귀하의 스프링 구성 XML에서는 추가 할 수 있습니다 DefaultAnnotationHandlerMapping및 설정 useDefaultSuffixPatternfalse(기본값은 true).

따라서 스프링 XML을 열거 mvc-config.xml나 호출하십시오.

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="useDefaultSuffixPattern" value="false" />
</bean>

이제 당신의 @PathVariable blahName(그리고 다른 모든 것들도) 모든 점을 포함한 성명을 포함해야합니다.

편집 : 여기 에 봄 API에 대한 링크가 있습니다


답변

또한 같은 문제가 발생하여 속성을 false로 설정해도 도움이되지 않았습니다. 그러나 API는 다음 과 같이 말합니다 .

“.xxx”접미사를 포함하거나 “/”로 끝나는 경로는 이미 기본 접미사 패턴을 사용하여 변환되지 않습니다.

RESTful URL에 “/ end”를 추가하려고했는데 문제가 해결되었습니다. 나는 해결책에 만족하지 않지만 효과가 있었다.

BTW, 나는 스프링 디자이너가이 “기능”을 추가 한 다음 기본적으로 켰을 때 무슨 생각을했는지 모르겠다. IMHO, 제거해야합니다.


답변

올바른 Java 구성 클래스 사용

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter
{

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

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer)
    {
        configurer.setUseSuffixPatternMatch(false);
    }
}


답변

이 핵으로 해결

1) 아래와 같이 @PathVariable에 HttpServletRequest를 추가했습니다.

 @PathVariable("requestParam") String requestParam, HttpServletRequest request) throws Exception { 

2) 요청에서 URL을 직접 가져옵니다 (이 수준에서는 잘리지 않음)

request.getPathInfo() 

점 (.)이있는 Spring MVC @PathVariable이 잘립니다.