1.若依附件下载跨域
源码:
package com.ruoyi.common.utils.file;import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.utils.StringUtils;/*** 文件处理工具类* * @author ruoyi*/
public class FileUtils extends org.apache.commons.io.FileUtils
{public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";/*** 输出指定文件的byte数组* * @param filePath 文件路径* @param os 输出流* @return*/public static void writeBytes(String filePath, OutputStream os) throws IOException{FileInputStream fis = null;try{File file = new File(filePath);if (!file.exists()){throw new FileNotFoundException(filePath);}fis = new FileInputStream(file);byte[] b = new byte[1024];int length;while ((length = fis.read(b)) > 0){os.write(b, 0, length);}}catch (IOException e){throw e;}finally{if (os != null){try{os.close();}catch (IOException e1){e1.printStackTrace();}}if (fis != null){try{fis.close();}catch (IOException e1){e1.printStackTrace();}}}}/*** 删除文件* * @param filePath 文件* @return*/public static boolean deleteFile(String filePath){boolean flag = false;File file = new File(filePath);// 路径为文件且不为空则进行删除if (file.isFile() && file.exists()){file.delete();flag = true;}return flag;}/*** 文件名称验证* * @param filename 文件名称* @return true 正常 false 非法*/public static boolean isValidFilename(String filename){return filename.matches(FILENAME_PATTERN);}/*** 检查文件是否可下载* * @param resource 需要下载的文件* @return true 正常 false 非法*/public static boolean checkAllowDownload(String resource){// 禁止目录上跳级别if (StringUtils.contains(resource, "..")){return false;}// 检查允许下载的文件规则if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))){return true;}// 不在允许下载的文件规则return false;}/*** 下载文件名重新编码* * @param request 请求对象* @param fileName 文件名* @return 编码后的文件名*/public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException{final String agent = request.getHeader("USER-AGENT");String filename = fileName;if (agent.contains("MSIE")){// IE浏览器filename = URLEncoder.encode(filename, "utf-8");filename = filename.replace("+", " ");}else if (agent.contains("Firefox")){// 火狐浏览器filename = new String(fileName.getBytes(), "ISO8859-1");}else if (agent.contains("Chrome")){// google浏览器filename = URLEncoder.encode(filename, "utf-8");}else{// 其它浏览器filename = URLEncoder.encode(filename, "utf-8");}return filename;}/*** 流文件下载** @param filePath* @param response*/public static void streamDownload(String filePath, HttpServletResponse response, String ctName, String ctFileType) {try {File file = new File(filePath);InputStream is = new BufferedInputStream(new FileInputStream(file));byte[] buffer = new byte[is.available()];is.read(buffer);is.close();response.reset();response.addHeader("Content-Disposition","attachment;filename*=utf-8''" + URLEncoder.encode(ctName, "utf-8")/* + ctFileType*/);// response.addHeader("Content-Disposition", "attachment;filename=" + new// String(file.getName().getBytes()));response.addHeader("Content-Length", "" + file.length());OutputStream toClient = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream");toClient.write(buffer);toClient.flush();toClient.close();} catch (IOException e) {e.printStackTrace();}}/*** 下载文件名重新编码** @param response 响应对象* @param realFileName 真实文件名* @return*/public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException{String percentEncodedFileName = percentEncode(realFileName);StringBuilder contentDispositionValue = new StringBuilder();contentDispositionValue.append("attachment; filename=").append(percentEncodedFileName).append(";").append("filename*=").append("utf-8''").append(percentEncodedFileName);response.setHeader("Content-disposition", contentDispositionValue.toString());}/*** 百分号编码工具方法** @param s 需要百分号编码的字符串* @return 百分号编码后的字符串*/public static String percentEncode(String s) throws UnsupportedEncodingException{String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());return encode.replaceAll("\\+", "%20");}
}
1.1 问题原因
1.2 解决办法,替换掉 response 的值
// 设置输出的格式response.reset();response.setCharacterEncoding("UTF-8");response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);response.addHeader("Access-Control-Allow-Origin", "*");//后端允许跨域response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
2.自定义附件下载代码
@Overridepublic void downloadFile(String id, HttpServletResponse response, String funNo) {TbFile tbFile = tbFileService.selectTbFileByCtId(Long.valueOf(id));if (tbFile == null) {throw new CustomException("文件下载失败,文件不存在,请联系管理员处理!");}String url = tbFile.getUrl().substring(6, tbFile.getUrl().length());// 下载本地文件String fileName = url; // 文件的默认保存名// 读到流中InputStream inStream = null;// 文件的存放路径try {inStream = new FileInputStream(tbFile.getUrl());} catch (FileNotFoundException e) {e.printStackTrace();}// 设置输出的格式response.reset();response.setCharacterEncoding("UTF-8");response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);response.addHeader("Access-Control-Allow-Origin", "*");//后端允许跨域response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");// 将文件名转成utf8的字符串形式try {response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), "utf-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 循环取出流中的数据byte[] b = new byte[100];int len;try {while ((len = inStream.read(b)) > 0)response.getOutputStream().write(b, 0, len);inStream.close();} catch (IOException e) {e.printStackTrace();}}