首先在文件下載時,請求類型需要設置編碼 :
request.setCharacterEncoding("UTF-8"); response.setContentType("application/octet-stream; charset=utf-8"); response.setHeader("Content-disposition", "attachment;" + UserAgentUtil.encodeFileName(request, fileName)); response.setHeader("Content-Length", String.valueOf(fileLength));
最終文件名處理交給UserAgentUtil的encodeFileName:
/** * 獲取客戶端瀏覽器類型、編碼下載文件名 * * @param request * @param fileName * @return String */ public static String encodeFileName(HttpServletRequest request, String fileName) { String userAgent = request.getHeader("User-Agent"); String rtn = ""; try { String new_filename = URLEncoder.encode(fileName, "UTF8"); // 如果沒有UA,則默認使用IE的方式進行編碼,因為畢竟IE還是占多數的 rtn = "filename=\"" + new_filename + "\""; if (userAgent != null) { userAgent = userAgent.toLowerCase(); // IE瀏覽器,只能采用URLEncoder編碼 if (userAgent.indexOf("msie") != -1) { rtn = "filename=\"" + new_filename + "\""; } // Opera瀏覽器只能采用filename* else if (userAgent.indexOf("opera") != -1) { rtn = "filename*=UTF-8''" + new_filename; } // Safari瀏覽器,只能采用ISO編碼的中文輸出 else if (userAgent.indexOf("safari") != -1) { rtn = "filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + "\""; } // Chrome瀏覽器,只能采用MimeUtility編碼或ISO編碼的中文輸出 else if (userAgent.indexOf("applewebkit") != -1) { new_filename = MimeUtility.encodeText(fileName, "UTF8", "B"); rtn = "filename=\"" + new_filename + "\""; } // FireFox瀏覽器,可以使用MimeUtility或filename*或ISO編碼的中文輸出 else if (userAgent.indexOf("mozilla") != -1) { rtn = "filename*=UTF-8''" + new_filename; } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return rtn; }
這樣在進行文件下載時,使用這個工具類對文件名進行一次編碼,就可以處理不同瀏覽器下載文件亂碼的問題了。
參考 開源中國