Spring 3 RequestMapping: obtener valor de ruta

¿Hay alguna forma de obtener el valor completo de la ruta requestMapping @PathVariable que se han analizado los valores de requestMapping @PathVariable ?

Es decir: /{id}/{restOfTheUrl} debería poder analizar /1/dir1/dir2/file.html en id=1 y restOfTheUrl=/dir1/dir2/file.html

Cualquier idea sería apreciada.

La parte no coincidente de la URL se expone como un atributo de solicitud denominado 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); ... } 

Acabo de encontrar ese problema que corresponde a mi problema. Utilizando las constantes de HandlerMapping, pude escribir una pequeña utilidad para ese propósito:

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

Esto ha estado aquí bastante tiempo pero publicando esto. Puede ser útil para alguien.

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

He usado Tuckey URLRewriteFilter para manejar elementos de ruta que contienen ‘/’ caracteres, ya que no creo que Spring 3 MVC los admita todavía.

http://www.tuckey.org/

Pones este filtro en tu aplicación y proporcionas un archivo de configuración XML. En ese archivo, usted proporciona reglas de reescritura, que puede usar para traducir los elementos de ruta que contienen caracteres ‘/’ a los parámetros de solicitud que Spring MVC puede manejar adecuadamente utilizando @RequestParam.

WEB-INF / web.xml:

  UrlRewriteFilter org.tuckey.web.filters.urlrewrite.UrlRewriteFilter   

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">   ^/(.*)/(.*)$ /$1?restOfTheUrl=$2  

Método del controlador:

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

Sí, el restOfTheUrl no devuelve solo el valor requerido, pero podemos obtener el valor mediante el uso de la coincidencia UriTemplate .

He resuelto el problema, así que aquí la solución de trabajo para el problema:

 @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 matchTemplate = new HashMap(); matchTemplate = template.match(restOfTheUrl); String value = matchTemplate.get("value"); /*variable `value` will contain the required detail.*/ } } 

Así es como lo hice. Puede ver cómo convierto elURI solicitado a una ruta del sistema de archivos (de lo que trata esta pregunta SO). Bonificación: y también cómo responder con el archivo.

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

Necesita usar 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))); 

Tengo un problema similar y resolví de esta manera:

 @RequestMapping(value = "{siteCode}/**/{fileName}.{fileExtension}") public HttpEntity 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 } 

Tenga en cuenta que req.getPathInfo() devolverá la ruta completa (con {siteCode} y {fileName}.{fileExtension} ) por lo que tendrá que procesar cómodamente.