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
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());
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:
fn
twice (note: encode()
, not encoder()
).