'Send a path containing slashes in Kotlin Spring mappings

Having trouble dealing with slashes in controller mappings in Kotlin Spring. My client application sends an absolute path ("C:/User/Documents/FolderX"), and should receive the content of the path's folder.

The request should look like this: http://localhost:8080/api/files/C:/User/Documents/FolderX

And I want to have access solely to the path/string "C:/User/Documents/FolderX".

Tried this at first:

@RestController
@RequestMapping("api/files")
class FileController(private val service: FileService)
{
    @GetMapping("/{path:.*}")
    fun retrieveFiles(@PathVariable path: String): MutableList<xFile> = service.retrieveFiles(path)
}

Which gives error code 404

Then tried this:

@RestController
@RequestMapping("api/files")
class FileController(private val service: FileService)
{
    @GetMapping("/**")
    fun retrieveFiles(@PathVariable path: String, request: HttpServletRequest): MutableList<xFile>
    {
        val thePath = request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();
        val bestMatchingPattern = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();

        val arguments = AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, thePath)

        val moduleName: String

        if (!arguments.isEmpty())
        {
            moduleName = (path + '/') + arguments
        }
        else
        {
            moduleName = path
        }

        return service.retrieveFiles(moduleName)
    }
}

Which gives this error (code 500):

Resolved [org.springframework.web.bind.MissingPathVariableException: Required URI template variable 'path' for method parameter type String is not present]



Solution 1:[1]

Using base64 encoding/decoding I was able to get it to work correctly.

@RestController
@RequestMapping("api/files")
class FileController(private val service: FileService)
{
    @GetMapping("/{encodedPath}")
    fun retrieveFiles(@PathVariable encodedPath: String): MutableList<xFile>
    {
        val decodedBytes = Base64.getDecoder().decode(encodedPath)
        val decodedString = String(decodedBytes)

        return service.retrieveFiles(decodedString)
    }
}

Then we just use a split or substring on decodedString to obtain the part of the path that we need!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1