[spring] Spring 3 RequestMapping : 경로 값 얻기

requestMapping @PathVariable값을 구문 분석 한 후 전체 경로 값을 얻는 방법이 있습니까?

즉 :
/{id}/{restOfTheUrl}구문 분석 할 수 있어야 /1/dir1/dir2/file.htmlid=1restOfTheUrl=/dir1/dir2/file.html

모든 아이디어를 부탁드립니다.



답변

URL의 일치하지 않는 부분은 다음과 같은 요청 속성으로 표시됩니다 HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE.

@RequestMapping("/{id}/**")
public void foo(@PathVariable("id") int id, HttpServletRequest request) {
    String restOfTheUrl = (String) request.getAttribute(
        HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
    ...
}


답변

내 문제에 해당하는 문제를 발견했습니다. HandlerMapping 상수를 사용하여 그 목적을 위해 작은 유틸리티를 작성할 수있었습니다.

/**
 * Extract path from a controller mapping. /controllerUrl/** => return matched **
 * @param request incoming request.
 * @return extracted path
 */
public static String extractPathFromPattern(final HttpServletRequest request){


    String path = (String) request.getAttribute(
            HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
    String bestMatchPattern = (String ) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);

    AntPathMatcher apm = new AntPathMatcher();
    String finalPath = apm.extractPathWithinPattern(bestMatchPattern, path);

    return finalPath;

}


답변

이것은 꽤 오래되었지만 이것을 게시했습니다. 누군가에게 유용 할 수 있습니다.

@RequestMapping( "/{id}/**" )
public void foo( @PathVariable String id, HttpServletRequest request ) {
    String urlTail = new AntPathMatcher()
            .extractPathWithinPattern( "/{id}/**", request.getRequestURI() );
}


답변

에 구축 파비앙 Kruba의 이미 훌륭한 대답 경우, 나는 그것이 좋은 것이라고 생각 **URL의 부분이 유사했다 방식으로, 주석을 통해 컨트롤러 메서드에 매개 변수로 제공 할 수 @RequestParam@PathVariable보다는 항상 유틸리티 방법을 사용하여 명시 적으로 HttpServletRequest. 이것이 어떻게 구현 될 수 있는지에 대한 예입니다. 바라건대 누군가가 유용하다고 생각합니다.

인수 리졸버와 함께 주석을 작성하십시오.

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WildcardParam {

    class Resolver implements HandlerMethodArgumentResolver {

        @Override
        public boolean supportsParameter(MethodParameter methodParameter) {
            return methodParameter.getParameterAnnotation(WildcardParam.class) != null;
        }

        @Override
        public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
            HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
            return request == null ? null : new AntPathMatcher().extractPathWithinPattern(
                    (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE),
                    (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE));
        }

    }

}

메소드 인수 해석자를 등록하십시오.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new WildcardParam.Resolver());
    }

}

컨트롤러 핸들러 메소드에서 주석을 사용하여 **URL 부분에 쉽게 액세스 할 수 있습니다 .

@RestController
public class SomeController {

    @GetMapping("/**")
    public void someHandlerMethod(@WildcardParam String wildcardParam) {
        // use wildcardParam here...
    }

}


답변

내장을 사용해야합니다 pathMatcher:

@RequestMapping("/{id}/**")
public void test(HttpServletRequest request, @PathVariable long id) throws Exception {
    ResourceUrlProvider urlProvider = (ResourceUrlProvider) request
            .getAttribute(ResourceUrlProvider.class.getCanonicalName());
    String restOfUrl = urlProvider.getPathMatcher().extractPathWithinPattern(
            String.valueOf(request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)),
            String.valueOf(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)));


답변

Spring 3 MVC가 아직 지원하지 않는다고 생각하기 때문에 Tuckey URLRewriteFilter를 사용하여 ‘/’문자가 포함 된 경로 요소를 처리했습니다.

http://www.tuckey.org/

이 필터를 앱에 넣고 XML 구성 파일을 제공합니다. 이 파일에는 ‘/’문자를 포함하는 경로 요소를 Spring MVC가 @RequestParam을 사용하여 올바르게 처리 할 수있는 요청 매개 변수로 변환하는 데 사용할 수있는 재 작성 규칙을 제공합니다.

WEB-INF / web.xml :

<filter>
  <filter-name>UrlRewriteFilter</filter-name>
  <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<!-- map to /* -->

WEB-INF / urlrewrite.xml :

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
    PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
    "http://tuckey.org/res/dtds/urlrewrite3.0.dtd">
<urlrewrite>
  <rule>
    <from>^/(.*)/(.*)$</from>
    <to last="true">/$1?restOfTheUrl=$2</to>
</urlrewrite>

컨트롤러 방법 :

@RequestMapping("/{id}")
public void handler(@PathVariable("id") int id, @RequestParam("restOfTheUrl") String pathToFile) {
  ...
}


답변

예, restOfTheUrl필요한 값만 반환하지 않지만 UriTemplate일치 를 사용하여 값을 얻을 수 있습니다 .

나는 문제를 해결 했으므로 여기에 문제에 대한 해결책이 있습니다.

@RequestMapping("/{id}/**")
public void foo(@PathVariable("id") int id, HttpServletRequest request) {
String restOfTheUrl = (String) request.getAttribute(
    HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
    /*We can use UriTemplate to map the restOfTheUrl*/
    UriTemplate template = new UriTemplate("/{id}/{value}");
    boolean isTemplateMatched = template.matches(restOfTheUrl);
    if(isTemplateMatched) {
        Map<String, String> matchTemplate = new HashMap<String, String>();
        matchTemplate = template.match(restOfTheUrl);
        String value = matchTemplate.get("value");
       /*variable `value` will contain the required detail.*/
    }
}