boot项目中添加小文件下载功能
1.本次需求是做一个生成License的服务页面
为每个客户添加常规数据后生成公钥秘钥并且加密后生成License文件和So文件,其中遇到了 一点小问题就是文件生成完之后的下载方法。
需求数据库中没有字段存放文件下载路径的地方。
所以在下相处了一种方案,在配置文件中配置一个固定的文件目录,然后每次根据当前数据的License No去生成一个文件夹,把文件生成在这个文件夹下,下载的时候就可以通过配置文件以及当前数据的License No去拼接一个完整的下载路径了。
本次博客就只展示一下关于Boot项目前端到接口下载的过程好了,整体流程过于复杂了。
2.前端按钮以及控制层接收
前端样式比较简单就是个超链接
<div class="btn-group-vertical btn_operators">
<a th:onclick="|javascript:g_needReloadPage = true;$('#J_modalLabel').text('下载');$('#J_modalIframe').attr('src', 'downLoadLicense?id=${record.id}');|">下载License</a>
<a th:onclick="|javascript:g_needReloadPage = true;$('#J_modalLabel').text('下载');$('#J_modalIframe').attr('src', 'downLoadSo?id=${record.id}');|">下载SO</a>
</div>
其中这个div对应的表单期缴到控制层的两个接口
@RequestMapping(value ="/downLoadLicense")
public void downloadLicense(@RequestParam(value = "id",required = false) Long id,
HttpServletRequest request, HttpServletResponse response) throws Exception {
String name= "LICENSE";
licenseRecordService.downLoad(licenseRecordService.findRecordByKey(id),request,response,name);
}
@RequestMapping(value ="/downLoadSo")
public void downloadSo(@RequestParam(value = "id",required = false) Long id,
HttpServletRequest request, HttpServletResponse response) throws Exception {
String name= "license.so";
licenseRecordService.downLoad(licenseRecordService.findRecordByKey(id),request,response,name);
}
只带了当前数据的主键ID,接口入参为Long id,Long id,HttpServletRequest request, HttpServletResponse response
因为文件下载的时候需要用到IO流往前端响应写出来所以方法不需要返回值,直接用void即可。
文件存储地址的配置卸载Properties文件中
#配置SO和License文件存储地址
config.file.path.so=D:\\Java\\License\\
config.file.path.license=D:\\Java\\License\\
接口中都调用同一个方法,但是入参变了,licenseRecordService.findRecordByKey(id)根据id查出当前数据并存放入一个实体类中,request,response,以及一个name,name在两个方法中我都定义了,一个是“LICENSE”另一个是“license.os”
因为我们生成的加密文件名都是固定的所以这样写效率高速度快--------如图
Interface接口层的方法
public void downLoad(LicenseRecord licenseRecord, HttpServletRequest request, HttpServletResponse response,String name) throws Exception;
实现类中的方法重写
@Override
public void downLoad(LicenseRecord licenseRecord, HttpServletRequest request, HttpServletResponse response,String name) throws Exception {
String FullPath = FileAndFolderUtil.getPath(path,licenseRecord)+name;
File packetFile = new File(FullPath);
String fileName = packetFile.getName(); //下载的文件名
File file = new File(FullPath);
// 如果文件名存在,则进行下载
if (file.exists()) {
// 配置文件下载
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
// 下载文件能正常显示中文
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 实现文件下载
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
System.out.println("Download the song successfully!");
} catch (Exception e) {
System.out.println("Download the song failed!");
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {//对应文件不存在
LOGGER.info("文件不存在请等待生成");
}
}
处理文件流的时候设置了response的请求头,UTF-8,该方法也可以用于txt文本文件的下载,可以防止文件的乱码
展示一下前端调用的反馈样式
文件存储目录看你自己的浏览器设置的默认文件下载地址了。