Весна 3 RequestMapping: получить значение пути
есть ли способ получить полный путь после requestMapping
@PathVariable
значения были разобраны?
это:
/{id}/{restOfTheUrl}
должен быть в состоянии разобрать /1/dir1/dir2/file.html
на id=1
и restOfTheUrl=/dir1/dir2/file.html
любые идеи будут оценены.
9 ответов:
несоответствующая часть 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() ); }
я использовал Tuckey URLRewriteFilter для обработки элементов пути, которые содержат символы'/', так как я не думаю, что Spring 3 MVC поддерживает их еще.
вы помещаете этот фильтр в свое приложение и предоставляете файл конфигурации 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">/?restOfTheUrl=</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.*/ } }
вот как я это сделал. Вы можете увидеть, как я конвертирую 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"); } }
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; }
вы должны использовать встроенный
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)));
у меня похожая проблема и я решил таким образом:
@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 }
отметим, что
req.getPathInfo()
вернет полный путь (с{siteCode}
и{fileName}.{fileExtension}
) Так что вам придется обрабатывать удобно.