因为第一次使用 spring boot 在开发项目, 在文件上传下载这块 出现了两个BUG: java
BUG1: 在服务器Jar包形式下,文件(图片)上传成功后, 浏览器访问不到;web
BUG2: 文件下载时, 系统报错: ajax
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 您的主机中的软件终止了一个已创建的链接....
BUG1: https://www.oschina.net/question/3681868_2281702spring
BUG2: 在百度和试验一波后,发现问题应该是ajax请求的问题, 只须要将下载接口开放为GET请求经过 链接来下载便可;apache
1, 文件上传工具类: 浏览器
package com.gy.fast.common.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.springframework.util.ResourceUtils; import org.springframework.web.multipart.MultipartFile; import com.gy.fast.common.exception.SysException; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; /** * 文件上传工具 * * @author geYang * @date 2018-06-13 */ public class UploadUtils { /** * 文件指定访问URL */ public static final String BASE_URL = "/files/"; /** * 文件指定存放目录 */ public static final String BASE_PATH = "uploadfiles/"; /** * 用户图片存放目录 */ public static final String USER_IMAGE = "userimage/"; /** * 其余文件存放目录 */ public static final String OTHERF = "outher/"; /** * 容许上传文件集合 */ protected static String[] ALLOW_FORMAT = { ".jpg", ".png", ".gif", ".jpeg", ".txt", ".zip", ".doc", ".docx", ".xls", ".xlsx" }; /** * 获取项目绝对路径 * @return String( E:\FrindHR\niuniu_lawyer_internal\niuer-law\target\classes ) * @author geYang * @date 2018-06-13 06:47 * */ public static String getClassFilePath() { try { String classPath = ResourceUtils.getURL("classpath:").getPath(); File classFile = new File(classPath); if (!classFile.exists()) { classFile = new File(""); } String classFilePath = classFile.getAbsolutePath(); System.out.println("classFilePath(项目根路径): " + classFilePath); return classFilePath; } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } /** * 文件存放的绝对路径 * @param path 默认为 OTHER(other) * @author geYang * @date 2018-06-13 07:06 * */ public static String getUploadFilePath(String path) { String classFilePath = getClassFilePath(); path = CommonUtil.isBlank(path) || path.equals(BASE_URL) || path.equals(BASE_PATH) ? OTHERF : path; File uploadFile = new File(classFilePath, BASE_PATH + path); if (!uploadFile.exists()) { uploadFile.mkdirs(); } String uploadFilePath = uploadFile.getAbsolutePath(); System.out.println("uploadFilePath(文件上传路径): " + uploadFilePath); return uploadFilePath; } /** * 文件上传 * @param file 文件 * @param path 存放目录 * @author geYang * @date 2018-06-13 07:09 * */ public static String upload(MultipartFile file, String path) { if (file.isEmpty()) { return null; } String oldfileName = file.getOriginalFilename(); String fileName = getfileName(oldfileName); String fileUrl = null; try { // 文件存放目录 String uploadFilePath = getUploadFilePath(path); uploadFile(file.getBytes(), uploadFilePath, fileName); fileUrl = getFileUrl(path, fileName); } catch (IOException e) { e.printStackTrace(); } return fileUrl; } /** * 获取文件访问路径 * */ public static String getFileUrl(String path, String fileName) { String fileUrl = BASE_URL + path + fileName; System.out.println("fileUrl(文件访问路径): " + fileUrl); return fileUrl; } /** * 获取文件存放路径(相对路径) * @param fileUrl 文件访问路径 * @return uploadfiles/outher/08.jpg * @author geYang * @date 2018-06-13 07:25 * */ private static String getUploadPath(String fileUrl) { String uploadPath = fileUrl.replace(BASE_URL, BASE_PATH); System.out.println("uploadPath(文件存放路径): " + uploadPath); return uploadPath; } /** * 获取文件存放全路径(绝对) * @param fileUrl * @return E:\FrindHR\niuniu_lawyer_internal\niuer-law\target\test-classes/uploadfiles/outher/08.jpg * @author geYang * @date 2018-06-13 07:24 * */ public static String getUploadPathAll(String fileUrl) { String uploadPathAll = getClassFilePath() + "/" + getUploadPath(fileUrl); System.out.println("uploadPathAll(文件存放绝对路径): " + uploadPathAll); return uploadPathAll; } /** * 生成随机文件名 * * @param originalName * @return * @author geYang * @date 2018-06-13 10:54 */ private static String getfileName(String originalName) { String suffix = getSuffix(originalName); StringBuffer name = new StringBuffer(); name.append(DateUtil.format(new Date(), "yyyyMMddHHmmss")).append(RandomUtil.randomString(5)).append(suffix); return name.toString(); } /** * 获取文件后缀名 */ public static String getSuffix(String name) { String suffix = name.substring(name.lastIndexOf(".")); if (!checkSuffix(suffix)) { throw new SysException("文件不合法"); } return suffix; } /** * 判断文件名是否合格 * @param name * @return * @author geYang * @date 2018-06-13 08:35 * */ public static boolean checkName(String name) { return checkSuffix(getSuffix(name)); } /** * 校验后缀名是否合法 * */ private static boolean checkSuffix(String suffix) { Set<String> setSuffix = new HashSet<>(Arrays.asList(ALLOW_FORMAT)); return setSuffix.contains(suffix); } /** * 文件上传 * */ public static void uploadFile(byte[] file, String filePath, String fileName) throws IOException { File targetFile = new File(filePath); if (!targetFile.exists()) { targetFile.mkdirs(); } FileOutputStream out = new FileOutputStream(filePath + "/" + fileName); out.write(file); out.flush(); out.close(); } /** * 获取文件下载数据 * @param url * @return * @author geYang * @date 2018-06-13 10:20 * */ private static byte[] getDownloadByte(String fileUrl) { try { String uploadPath = getUploadPathAll(fileUrl); InputStream inputStream = new FileInputStream(new File(uploadPath)); byte[] data = new byte[inputStream.available()]; inputStream.read(data); inputStream.close(); return data; } catch (IOException e) { e.printStackTrace(); throw new SysException("文件下载异常"); } } /** * 文件下载 * @param fileUrl 文件访问路径 * @param fileName 定义下载文件名,不带后缀 * @param response * @throws IOException * @author geYang * @date 2018-06-13 10:30 * */ public static void download(String fileUrl, String fileName ,HttpServletResponse response) throws IOException { // 文件下载 byte[] downloadByte = getDownloadByte(fileUrl); if (downloadByte == null) { throw new SysException("下载文件不存在"); } int downloadByteLength = downloadByte.length; response.reset(); fileName = URLEncoder.encode(fileName.trim()+getSuffix(fileUrl), "UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=\""+ fileName +"\""); response.addHeader("Content-Length", String.valueOf(downloadByteLength)); response.setContentType("application/octet-stream; charset=UTF-8"); IOUtils.write(downloadByte, response.getOutputStream()); } }
2, 访问文件时 spring boot 路径处理:bash
/** * WebMvc配置 * @author geYang * @date 2018-05-14 */ @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 上传图片访问目录: 若是有权限拦截的话,应该将 (UploadUtils.BASE_URL + "**") 放行 registry.addResourceHandler(UploadUtils.BASE_URL + "**").addResourceLocations("file:"+ UploadUtils.getClassFilePath()+ "/" + UploadUtils.BASE_PATH); } }