8

There is a task to pass file path as @PathVariable in Spring MVC to REST Service with GET request.

We can easily do it with POST sending String of file path in JSON.

How we can do with GET request and @Controller like this?

@RequestMapping(value = "/getFile", method = RequestMethod.GET)
public File getFile(@PathVariable String path) {
    // do something
}

Request:

GET /file/getFile/"/Users/user/someSourceFolder/8.jpeg"
Content-Type: application/json
J-Alex
  • 6,881
  • 10
  • 46
  • 64
  • omg... i have a question. you want to upload file? or you want to send file path? – 0gam Jul 19 '16 at 06:37
  • I want to download file - sending it's path. There is some requirements that I have to do it with GET request. – J-Alex Jul 19 '16 at 06:43

3 Answers3

5

You should define your controller like this:

@RequestMapping(value = "/getFile/{path:.+}", method = RequestMethod.GET)
public File getFile(@PathVariable String path) {
    // do something
}
Blank
  • 12,308
  • 1
  • 14
  • 32
  • 1
    Can you explain `:.+`? – ChiefTwoPencils Jul 19 '16 at 07:06
  • 3
    This `.+` is a regexp match, it will not truncate `.jpg` in your path. – Blank Jul 19 '16 at 07:27
  • 1
    I cannot pass parameter that way. For example, I have /var/folders/gc/6403595805123870815.pdf this full path to file. When I'm passing it like {{URL}}/file/getFile/var/folders/gc/6403595805123870815.pdf It's not worked and 404 is occurred. – J-Alex Jul 19 '16 at 10:40
  • @J-Alex Because your `path` has slash `/` there, so this error happened, please check here http://stackoverflow.com/questions/3686808/spring-3-requestmapping-get-path-value. – Blank Jul 20 '16 at 01:38
1

Ok. you use to get pattern. sending get pattern url.

Use @RequestParam.

@RequestMapping(value = "/getFile", method = RequestMethod.GET)
public File getFile(@RequestParam("path") String path) {
    // do something
}

and if you use @PathVariable.

@RequestMapping(value = "/getFile/{path}", method = RequestMethod.POST)
public File getFile(@PathVariable String path) {
    // do something
}
0gam
  • 1,343
  • 1
  • 9
  • 21
  • Path variable not worked for me, how you will send the get request with this path? How about slashes? @RequestParam works fine, thanks. – J-Alex Jul 19 '16 at 10:42
  • @PathVariable send path : ... /getFile/..Users/user/someSourceFolder/8.jpeg use POST request. – 0gam Jul 20 '16 at 01:04
  • You want GET request. use @RequestParam. – 0gam Jul 20 '16 at 01:04
  • I'm not the one that downvoted, just my 2 cents: maybe downvoted becaues using request param instead of path variable isn't "best practice" for REST API design regarding URL patterns. If the path is the unique identifier, then it should be in the URL. Not sure if I've ever seen a popular SaaS product with an API that uses file paths (and not UUIDs for example) as the unique identifiers and having a REST API. – Mathias Conradt Dec 18 '16 at 14:55
  • yeah. i agree your comment. – 0gam Dec 19 '16 at 00:33
1

What I did works with relative paths to download/upload files in Spring.

@RequestMapping(method = RequestMethod.GET, path = "/files/**")
@NotNull
public RepositoryFile get(@PathVariable final String repositoryId, 
        @PathVariable final String branchName,
        @RequestParam final String authorEmail, 
        HttpServletRequest request) {
    String filePath = extractFilePath(request);
    ....
}

And the utilitary function I created within the controller :

private static String extractFilePath(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(); 
        return apm.extractPathWithinPattern(bestMatchPattern, path);
    }