Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring3请求映射:获取路径值_Spring_Spring Mvc_Request Mapping - Fatal编程技术网

Spring3请求映射:获取路径值

Spring3请求映射:获取路径值,spring,spring-mvc,request-mapping,Spring,Spring Mvc,Request Mapping,解析requestMapping@PathVariable值后,是否有方法获取完整的路径值 即: /{id}/{restofurl}应该能够将/1/dir1/dir2/file.html解析为id=1和restofurl=/dir1/dir2/file.html 如果您有任何想法,我们将不胜感激。URL中不匹配的部分将作为名为HandlerMapping的请求属性公开。处理程序映射属性中的路径\u: @RequestMapping("/{id}/**") public void foo(@Pat

解析
requestMapping
@PathVariable
值后,是否有方法获取完整的路径值

即:
/{id}/{restofurl}
应该能够将
/1/dir1/dir2/file.html
解析为
id=1
restofurl=/dir1/dir2/file.html


如果您有任何想法,我们将不胜感激。

URL中不匹配的部分将作为名为
HandlerMapping的请求属性公开。处理程序映射属性中的路径\u

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

我已经使用Tuckey URLRewriteFilter来处理包含“/”字符的路径元素,因为我认为Spring3MVC还不支持它们

您将此筛选器放入应用程序,并提供一个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 /* -->

刚刚发现了与我的问题相对应的问题。使用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(value = "{siteCode}/**/{fileName}.{fileExtension}")
public HttpEntity<byte[]> getResource(@PathVariable String siteCode,
        @PathVariable String fileName, @PathVariable String fileExtension,
        HttpServletRequest req, HttpServletResponse response ) throws IOException {
    String fullPath = req.getPathInfo();
    // Calling http://localhost:8080/SiteXX/images/argentine/flag.jpg
    // fullPath conentent: /SiteXX/images/argentine/flag.jpg
}
@RequestMapping(value=“{siteCode}/**/{fileName}.{fileExtension}”)
公共HttpEntity getResource(@PathVariable String siteCode,
@PathVariable字符串文件名,@PathVariable字符串文件扩展名,
HttpServletRequest请求,HttpServletResponse响应)引发IOException{
字符串fullPath=req.getPathInfo();
//召唤http://localhost:8080/SiteXX/images/argentine/flag.jpg
//完整路径客户:/SiteXX/images/agentine/flag.jpg
}
请注意,
req.getPathInfo()
将返回完整的路径(带有
{siteCode}
{fileName}.{fileExtension}
),因此您必须方便地进行处理。

私有最终静态字符串映射=“/foo/*”;
private final static String MAPPING = "/foo/*";

@RequestMapping(value = MAPPING, method = RequestMethod.GET)
public @ResponseBody void foo(HttpServletRequest request, HttpServletResponse response) {
    final String mapping = getMapping("foo").replace("*", ""); 
    final String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
    final String restOfPath = url.replace(mapping, "");
    System.out.println(restOfPath);
}

private String getMapping(String methodName) {
    Method methods[] = this.getClass().getMethods();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName() == methodName) {
            String mapping[] = methods[i].getAnnotation(RequestMapping.class).value();
            if (mapping.length > 0) {
                return mapping[mapping.length - 1];
            }
        }
    }
    return null;
}
@RequestMapping(值=映射,方法=RequestMethod.GET) public@ResponseBody void foo(HttpServletRequest请求,HttpServletResponse响应){ 最终字符串映射=getMapping(“foo”)。替换(“*”,”);
最终字符串路径=(字符串)request.getAttribute(HandlerMapping.path\u在\u HANDLER\u MAPPING\u属性中); 最后一个字符串restOfPath=url.replace(映射为“”); System.out.println(restOfPath); } 私有字符串getMapping(字符串方法名){ 方法方法[]=this.getClass().getMethods(); for(int i=0;i0){ 返回映射[mapping.length-1]; } } } 返回null; }
是的,
restofurl
不仅返回所需的值,而且我们可以使用
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.*/
    }
}
@RequestMapping(“/{id}/**”)
public void foo(@PathVariable(“id”)int-id,HttpServletRequest){
String restofurl=(String)request.getAttribute(

HandlerMapping.PATH_在_HANDLER_MAPPING_属性中); /*我们可以使用UriTemplate映射RESTOfUrl*/ UriTemplate=newUriTemplate(“/{id}/{value}”); 布尔值isTemplateMatched=template.matches(restofurl); 如果(isTemplateMatched){ Map matchTemplate=新建HashMap(); matchTemplate=template.match(restofurl); 字符串值=matchTemplate.get(“值”); /*变量'value'将包含所需的详细信息*/ } }
以下是我是如何做到的。您可以看到我如何将requestedURI转换为文件系统路径(这个SO问题是关于什么的)。奖励:以及如何响应文件

@RequestMapping(value = "/file/{userId}/**", method = RequestMethod.GET)
public void serveFile(@PathVariable("userId") long userId, HttpServletRequest request, HttpServletResponse response) {
    assert request != null;
    assert response != null;

    // requestURL:  http://192.168.1.3:8080/file/54/documents/tutorial.pdf
    // requestURI:  /file/54/documents/tutorial.pdf
    // servletPath: /file/54/documents/tutorial.pdf
    // logger.debug("requestURL: " + request.getRequestURL());
    // logger.debug("requestURI: " + request.getRequestURI());
    // logger.debug("servletPath: " + request.getServletPath());

    String requestURI = request.getRequestURI();
    String relativePath = requestURI.replaceFirst("^/file/", "");

    Path path = Paths.get("/user_files").resolve(relativePath);
    try {
        InputStream is = new FileInputStream(path.toFile());  
        org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
        response.flushBuffer();
    } catch (IOException ex) {
        logger.error("Error writing file to output stream. Path: '" + path + "', requestURI: '" + requestURI + "'");
        throw new RuntimeException("IOError writing file to output stream");
    }
}

这已经在这里有一段时间了,但是发布了这个。可能对某人有用

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

您需要使用内置的
路径匹配器

@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)));
在此基础上,我认为如果URL的
***
部分可以通过注释作为控制器方法的参数提供,这将是一件好事,其方式类似于
@RequestParam
@PathVariable
,而不是总是使用明确需要
HttpServletRequest
的实用程序方法。下面是一个如何实现的示例。希望有人觉得它有用

创建注释以及参数解析器:

@Target(ElementType.PARAMETER)
@保留(RetentionPolicy.RUNTIME)
@记录
公共@接口通配符参数{
类解析器实现HandlerMethodArgumentResolver{
@凌驾
公共布尔支持参数(MethodParameter MethodParameter){
返回methodParameter.getParameterAnnotation(WildcardParam.class)!=null;
}
@凌驾
公共对象resolveArgument(MethodParameter MethodParameter、ModelAndViewContainer ModelAndViewContainer、NativeWebRequest NativeWebRequest、WebDataBinder Factory WebDataBinder Factory)引发异常{
HttpServletRequest=nativeWebRequest.getNativeRequest(HttpServletRequest.class);
返回请求==null?null:新AntPathMatcher().extractPathWithinPattern(
(字符串)request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_属性),

(String)request.getAttribute(HandlerMapping.PATH_在\u HANDLER\u MAPPING\u属性中)); } } }
注册方法参数解析程序:

@配置
公共类WebMvcConfig实现WebMVCConfiguer{
@凌驾
公共无效AddArgumentResolver(列表解析程序){
add(新的WildcardParam.Resolver());
}
}
使用控制器处理程序方法中的注释可以轻松访问URL的
**
部分:

@RestController
公共类控制器{
@GetMapping(“/**”)
@RequestMapping( "/{id}/**" )
public void foo( @PathVariable String id, HttpServletRequest request ) {
    String urlTail = new AntPathMatcher()
            .extractPathWithinPattern( "/{id}/**", request.getRequestURI() );
}
@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)));