Why does Java automatically decode / in URI encoded filenames?

后端 未结 2 1922
囚心锁ツ
囚心锁ツ 2021-01-18 06:43

I have a servlet that needs to write out files that have a user-configurable name. I am trying to use URI encoding to properly escape special characters, but the JRE appear

相关标签:
2条回答
  • 2021-01-18 07:12

    I think that @BalusC has nailed the direct problem in your code. I'd just like to point out some other issuse

    The dir.toURI().toASCIIString() and URLEncoder.encoder(fn, "UTF-8").toString() expressions actually do rather different things.

    • The first one, encodes the URI as a string, applying the URI encoding rules according to the URI grammar. So for example, a '/' in the path component will not be encoded but a '/' in the query or fragment components will be encoded as %2F.

    • The second one, encodes the fn String applying the encoding rules without reference to the content of the string.

    The File(URI) constructor's mapping from a file URI to a File is system dependent and undocumented. I'm a bit surprised that it decodes the %2F, but it does what it does, and @BalusC explains why. The take-away is that it is potentially problematic to use a mechanism ("file:" URIs) that are explicitly system dependent.

    Finally, it is wrong to combine those URI component strings like that. It should be either

    URI uri = new URI(
            dir.toURI().toString() +
            URLEncoder.encoder(fn, "UTF-8").toString();
    

    or

    URI uri = new URI(
            dir.toURI().toASCIIString() +
            URLEncoder.encoder(fn, "ASCII").toString());
    
    0 讨论(0)
  • 2021-01-18 07:33

    The new File(URI) constructs the file based on the path as obtained by URI#getPath() instead of -what you expected- URI#getRawPath(). This look like a feature "by design".

    You have 2 options:

    1. Run URLEncoder#encode() on fn twice (note: encode(), not encoder()).
    2. Use new File(String) instead.
    0 讨论(0)
提交回复
热议问题