É importante fazer decode da URI antes de obter o nome do arquivo - URLDecoder.decode
. Segue como fica a função do Servlet:
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String relativePathStr = URLDecoder.decode(req.getRequestURI(), "UTF-8").split("/file/")[1];
String fullPathStr = FileSaver.getPath(relativePathStr);
Path sourcePath = Paths.get(fullPathStr);
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentType = fileNameMap.getContentTypeFor("file:" + sourcePath);
res.reset();
res.setContentType(contentType);
res.setHeader("Content-Length", String.valueOf(Files.size(sourcePath)));
res.setHeader("Content-Disposition", String.format("\"%s\"", sourcePath.getFileName()));
FileSaver.transfer(fullPathStr, res.getOutputStream());
}