三、方式三(ClassPathResource)(`Spring Boot 项目-推荐`)
本文提供多种获取resources目录下文件的方式
一、方式一(getClassLoader)
使用getResourceAsStream方法获取流,在SpringBoot中所有文件都在jar包中,没有一个实际的路径,因此可以使用以下方式。
/** * 直接使用getResourceAsStream方法获取流 * * @param fileName * @throws IOException */publicvoidfunction4(String fileName)throws IOException { InputStream in = this.getClass().getClassLoader().getResourceAsStream(fileName); }
二、方式二(getClass())
使用getResourceAsStream方法获取流,不使用getClassLoader可以使用getResourceAsStream("/测试.txt")直接从resources根路径下获取,SpringBoot中所有文件都在jar包中,没有一个实际的路径,因此可以使用以下方式。
/** * 直接使用getResourceAsStream方法获取流 * * @param fileName * @throws IOException */publicvoidfunction5(String fileName)throws IOException { InputStream in = this.getClass().getResourceAsStream("/" + fileName); }
三、方式三(ClassPathResource)(Spring Boot 项目-推荐)
通过ClassPathResource类获取文件流,SpringBoot中所有文件都在jar包中,没有一个实际的路径,因此可以使用以下方式。
/** * 通过ClassPathResource类获取,建议SpringBoot中使用 * * @param fileName * @throws IOException */publicvoidfunction6(String fileName)throws IOException { ClassPathResource classPathResource = new ClassPathResource(fileName); InputStream inputStream = classPathResource.getInputStream(); getFileContent(inputStream); }
四、三种方式区别对别
假设 fileName = "excel/模板.xlsx"
// 方式1:ClassLoader - 始终从 classpath 根路径InputStream in = this.getClass().getClassLoader().getResourceAsStream(fileName);// 实际查找路径:classpath:/excel/模板.xlsx// 方式2:Class - 需要手动加 / 才能到根路径InputStream in = this.getClass().getResourceAsStream("/" + fileName);// 实际查找路径:classpath:/excel/模板.xlsx// 方式3:ClassPathResource - 默认从根路径,可加 / 或不加ClassPathResource resource = new ClassPathResource(fileName);InputStream inputStream = resource.getInputStream();// fileName 可以是 "excel/模板.xlsx" 或 "/excel/模板.xlsx",效果相同
4.1 路径处理详细对比
| | | |
|---|
| ClassLoader | "excel/模板.xlsx" | classpath:/excel/模板.xlsx | |
| ClassLoader | "/excel/模板.xlsx" | classpath:/excel/模板.xlsx | |
| Class | "excel/模板.xlsx" | classpath:/包路径/excel/模板.xlsx | |
| Class | "/excel/模板.xlsx" | classpath:/excel/模板.xlsx | |
| ClassPathResource | "excel/模板.xlsx" | classpath:/excel/模板.xlsx | |
| ClassPathResource | "/excel/模板.xlsx" | classpath:/excel/模板.xlsx | |
4.2 核心优势对比
| | Class.getResourceAsStream |
|---|
| | |
| | |
| | |
| | |
| | |
| | |
4.3 总结建议
| | |
|---|
| ClassPathResource | |
| ClassPathResource | |
| Class.getResourceAsStream | |
| ClassPathResource | |
| ClassPathResource + @Value | |
五、Excel模板下载
在这里插入图片描述5.1 Controller
/** * 模板导出 * * @param response response */@GetMapping("/exportTemplate")publicvoidexportTemplate(HttpServletResponse response){ manageService.exportTemplate(response); }
5.2 Service
/** * 模板导出 * * @param response response */voidexportTemplate(HttpServletResponse response);
5.3 Impl
this.getClass().getClassLoader().getResourceAsStream方式
@OverridepublicvoidexportTemplate(HttpServletResponse response){try { String finalFileName = "模板.xlsx"; InputStream fileStream;byte[] bytes = newbyte[300000]; fileStream = this.getClass().getResourceAsStream("/excel/模板.xlsx"); fileStream.read(bytes); OutputStream outputStream = null;try { outputStream = response.getOutputStream();// 设值返回文件属性,浏览器会根据属性调用下载文件方法 response.addHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(finalFileName, "utf-8"));// 设值文件大小属性,浏览器用于判断文件是否写完 response.addHeader("Content-Length", "" + bytes.length);// 前端获取文件名,需要解码 response.addHeader("downLoadName", URLEncoder.encode(finalFileName, "utf-8"));// 定义输出流 outputStream = new BufferedOutputStream(response.getOutputStream());// 定义输出类型为二进制流输出 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("UTF-8"); outputStream.write(bytes); outputStream.flush(); } catch (Exception e) {throw BusinessException.buildBusinessExceptionAlert("程序异常"); } finally { outputStream.close(); } } catch (BusinessException error) {throw error; } catch (Exception e) { log.error("模板导出异常", e);thrownew BusinessException("-1", "模板导出异常,请稍后重试"); } }
ClassPathResource方式
@OverridepublicvoidexportTemplate(HttpServletResponse response){ String fileName = "模板.xlsx"; String resourcePath = "/excel/模板.xlsx";// 使用 ClassPathResource 统一处理 ClassPathResource resource = new ClassPathResource(resourcePath);try {// 1. 检查资源if (!resource.exists()) {throw BusinessException.buildBusinessExceptionAlert("模板文件不存在"); }// 2. 设置响应头(包括准确的 Content-Length) response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())); response.setHeader("downLoadName", URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())); response.setContentLengthLong(resource.contentLength()); // ✅ 准确设置大小// 3. 流拷贝try (InputStream inputStream = resource.getInputStream(); OutputStream outputStream = response.getOutputStream()) { FileCopyUtils.copy(inputStream, outputStream); outputStream.flush(); } } catch (BusinessException e) {throw e; } catch (Exception e) { log.error("模板导出异常", e);thrownew BusinessException("-1", "模板导出异常,请稍后重试"); }}


