springboot实现文件下载(打jar包可下载,可解决下载文件损坏)
前端代码:
downloadTemplate(){ let url = `${window._CONFIG['domianURL']}/invoice/bmsBillRiskverification/downloadTemplate`; window.location.href = url; }
后端代码:
/** * @param response * @功能描述 下载文件: */ @RequestMapping("/downloadTemplate") public void downloadTemplate(HttpServletResponse response) { InputStream inputStream = null; OutputStream outputStream = null; try { // 直接获取流 inputStream = FileUtil.class.getClassLoader().getResourceAsStream("static/busfile/导入模板.xls"); response.setContentType("application/octet-stream"); String name = java.net.URLEncoder.encode("导入模板.xls", "UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLDecoder.decode(name, "ISO-8859-1") ); outputStream = response.getOutputStream(); if( inputStream != null) { // 调用工具类 byte[] results = FileCopyUtils.copyToByteArray(inputStream); outputStream.write(results); outputStream.flush(); } } catch (IOException e) { log.error("文件下载失败, e"); } finally { IOUtils.closeQuietly(outputStream); IOUtils.closeQuietly(inputStream); } }
文件所在位置:
配置maven打包不压缩
<!-- 避免font文件的二进制文件格式压缩破坏 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.1.0</version> <configuration> <nonFilteredFileExtensions> <nonFilteredFileExtension>woff</nonFilteredFileExtension> <nonFilteredFileExtension>woff2</nonFilteredFileExtension> <nonFilteredFileExtension>eot</nonFilteredFileExtension> <nonFilteredFileExtension>ttf</nonFilteredFileExtension> <nonFilteredFileExtension>svg</nonFilteredFileExtension> <nonFilteredFileExtension>xls</nonFilteredFileExtension> <nonFilteredFileExtension>xlsx</nonFilteredFileExtension> </nonFilteredFileExtensions> </configuration> </plugin>
遇到的问题总结:
1、直接访问图片会被校验登录拦截,故需要配置不拦截该请求
2、上面的下载是直接通过获取文件流的方式,如果不使用这种方式,先获取静态文件路径再下载,会出现:在idea设计器中可以下载,但是打成jar包无法下载。原因是jar包本身是一个文件,没有办法获取其中的文件路径。
错误代码如下:
/** * @param response * @功能描述 下载文件: */ @RequestMapping("/downloadTemplate") public void download(HttpServletResponse response) { String path = ClassUtils.getDefaultClassLoader().getResource("").getPath(); String filePath = path + "static/busfile/导入模板.xls"; try { // path是指想要下载的文件的路径 File file = new File(filePath); log.info(file.getPath()); // 获取文件名 String filename = file.getName(); // 获取文件后缀名 String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase(); log.info("文件后缀名:" + ext); // 将文件写入输入流 FileInputStream fileInputStream = new FileInputStream(file); InputStream fis = new BufferedInputStream(fileInputStream); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header response.setCharacterEncoding("UTF-8"); //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存 //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3" // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称 response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); // 告知浏览器文件的大小 response.addHeader("Content-Length", "" + file.length()); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); outputStream.write(buffer); outputStream.flush(); } catch (IOException ex) { ex.printStackTrace(); } }
3、下载时遇到已损坏,是因为maven打包时对文件进行了压缩,所以需要配置不压缩指定格式文件。