最近在开发一个管理系统,涉及到文件的上下载问题,但是我发现Java中文或者说对编码比较敏感(以前用PHP没感觉到),然后我在写一个上下载功能时就发现问题比较明显,下载英文然后无空格的文件下载完全正常,但是当下载含有中文文件名的文件时发现下载的文件名并为更名,一开始我以为是Header 中 Content-Disposition 未设置正确导致的,但是后来发现并不是,于是网上搜索了相关资料,的确存在对中文文件名支持不友好的情况,然后整理了相关资料,引用到了自己的代码里,请看下面这段代码,就是正确解决了这个问题,特别请看注释。
if(file.exists()){ // 设置文件流 httpServletResponse.setContentType("application/octet-stream"); // 为防止中文文件名的乱码显示 //filename =new String(filename.getBytes("ISO8859-1"),"UTF-8"); // 编码文件名 filename = URLEncoder.encode(filename,"UTF-8"); // 编码后文件名中的空格被替换为“+”号,所以此处将替换编码后文件名中“+”号为UTF-8中空格的“%20”编码 filename = filename.replaceAll("\\+","%20"); // 设置下载文件内容长度 httpServletResponse.setContentLengthLong(file.length()); // 设置文件名 httpServletResponse.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"",filename)); System.out.println(httpServletResponse.getHeader("Content-Disposition")); byte[] bytes = new byte[1024]; FileInputStream fileInputStream =null; BufferedInputStream bufferedInputStream = null; OutputStream outputStream = null; try { fileInputStream = new FileInputStream(file); bufferedInputStream = new BufferedInputStream(fileInputStream); outputStream = httpServletResponse.getOutputStream(); Integer len = 0; while((len=fileInputStream.read(bytes))>0){ outputStream.write(bytes,0,len); } // 成功下载文件 } catch (Exception e) { e.printStackTrace(); }finally { if(fileInputStream!=null){ try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if(bufferedInputStream!=null){ try { bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if(outputStream!=null){ try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }