问题描述:今天在实现文件下载并指定文件名称时,遇到文件下载在Google 浏览器下载正常,指定文件名称汉字未乱码,但是在IE11 浏览器上,指定文件名称汉字乱码。
问题产生原因:
- Chrome浏览器可以自动执行两次URL解码,所以下载的文件名是正常。
- IE浏览器只执行一次URL解码,所以下载的文件名是乱码
解决思路:筛选请求头信息,判别是IE浏览器还是Google 浏览器,对文件名称做对应处理
Chrome 浏览器指定文件下载名称仅重新指定编码格式="ISO-8859-1"
IE浏览器指定文件下载名称需要进行URLEncoder.encode 加码,并指定编码格式"utf-8"
核心功能代码:
判断浏览器是否为IE:
/**
* 判断是否是IE浏览器
*
* @param userAgent
* @return
*/
public static boolean isIE(HttpServletRequest request) {
String userAgent = request.getHeader("User-Agent").toLowerCase();
boolean isIe = false;
if (userAgent.contains("msie") || userAgent.contains("trident") || userAgent.contains("edge")) {
isIe = true;
}
return isIe;
}
文件下载核心功能代码:
@ApiOperation(value = "指定文件ZIP下载 ")
@RequestMapping(value="/viewZip", method= {RequestMethod.GET})
public void viewZip(@RequestParam @ApiParam(name="sid", value="sid", required= true) Long sid,HttpServletResponse response) throws UnsupportedEncodingException {
HttpServletRequest request = HttpContextUtils.getRequest();
//TODO 根据文件所属(工程,案卷)验证权限,没有权限抛出异常.
UserDownload download = userDownloadService.selectByPrimaryKey(sid);
String pdfDir = null;
if(download != null){
pdfDir = transPath(download.getDownloadAddress());
if(StringUtils.isNotEmpty(pdfDir)){
File file = new File(pdfDir);
response.setContentType("application/octet-stream");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.addHeader("Content-Length", "" + file.length());
if(isIE(request)){
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", URLEncoder.encode(file.getName(), "utf-8")));
} else {
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", new String(file.getName().getBytes(),"ISO-8859-1")));
}
BufferedInputStream bufferedStream = null;
ServletOutputStream ros = null;
try {
// 打开指定文件的流信息
bufferedStream = new BufferedInputStream(new FileInputStream(file));
ros = response.getOutputStream();
// 写出流信息
int i;
while ((i = bufferedStream.read()) != -1) {
ros.write(i);
}
ros.flush();
} catch (Exception e) {
log.error("文件路径读取异常 : "+ pdfDir);
} finally {
IOUtils.closeQuietly(bufferedStream);
IOUtils.closeQuietly(ros);
}
}else{
log.warn("非法访问未授权文件" + JacksonUtil.toJson(securityUtils.getAuthUserDetails(request)));
}
}
}