场景
前端通过js 调用Java后端的文件下载功能, 后端在正式下载前,会检查下载的文件是否存在,如果不存在,则输出脚本给前端,告诉前端文件不存在;如果存在,则以附件的方式传送数据给前端。
但我在输出脚本给前端时, java 报错,提示:java.io.CharConversionException: Not an ISO 8859-1 character: [下]
源代码
/**下载文件*/
@RequestMapping(value = "/downfile")
public void doDownfile(String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
ServletContext servletContext = request.getServletContext();
// 获取要下载的文件的真实路径
String realPath = servletContext.getRealPath("/upload/");
fileName = new String(fileName.getBytes("gbk"), "iso8859-1");
File downloadFile = new File(realPath, fileName);
ServletOutputStream out = response.getOutputStream();
// 判断文件是否存在
if (! downloadFile.exists()) {
logger.error("下载文件不存在:{}" , realPath + fileName );
response.setContentType("text/html; charset=UTF-8"); //转码
out.println("<script>");
out.println("alert('下载文件不存在!');");
out.println("</script>");
out.flush();
out.close();
}else {
logger.info("下载文件:{}" , realPath + fileName );
// 文件下载时,是使用字节流格式,所以不能使用response.getWriter()-->返回PrintWriter是字符流
// 获取输出字节流恶意使用response.
// 设置响应是以附件形式,不用设置Content-Type了
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
// 利用FileUtils将文件读入字节数组,然后返回给客户端。
out.write(FileUtils.readFileToByteArray(downloadFile));
out.flush();
out.close();
}
}
问题原因
ServletOutputStream out 只支持单字节的 8859-1 的内容,
当输出中文时,改成 PrintWriter out
解决方法
修改代码如下,问题解决
/**下载文件*/
@RequestMapping(value = "/downfile")
public void doDownfile(String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
ServletContext servletContext = request.getServletContext();
// 获取要下载的文件的真实路径
String realPath = servletContext.getRealPath("/upload/");
fileName = new String(fileName.getBytes("gbk"), "iso8859-1");
File downloadFile = new File(realPath, fileName);
// 判断文件是否存在
if (! downloadFile.exists()) {
logger.error("下载文件不存在:{}" , realPath + fileName );
response.setContentType("text/html; charset=UTF-8"); //转码
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("alert('下载文件不存在!');");
out.println("</script>");
out.flush();
out.close();
}else {
logger.info("下载文件:{}" , realPath + fileName );
// 文件下载时,是使用字节流格式,所以不能使用response.getWriter()-->返回PrintWriter是字符流
// 获取输出字节流恶意使用response.
ServletOutputStream out = response.getOutputStream();
// 设置响应是以附件形式,不用设置Content-Type了
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
// 利用FileUtils将文件读入字节数组,然后返回给客户端。
out.write(FileUtils.readFileToByteArray(downloadFile));
out.flush();
out.close();
}
}
看红色框修改的地方。