前台+后台 java下载服务器、本地文件(下载tomcat配置的虚拟路径下文件)指定任意保存路径,可以用于SSM框架
背景:java web网站与APP项目共同部署在服务器上,APP有一个上传图片、文件的功能,网站需要查看下载APP上传的图片。
这时候需要考虑遇到一个问题:APP将文件上传到服务器上并且上传到的是项目内的地址是没问题的,但是因为重新部署或Tomcat突然犯抽导致需要重装什么的,以前上传的图片和文件可能会丢失。所以可以将文件和图片上传到项目外,可以采用配置Tomcat的虚拟路径。同时还要解决的是文件下载问题。
A 首先看一下虚拟路径的配置以及图片访问
1.采用配置Tomcat的虚拟路径, 打开 tomcat文件夹下--conf文件夹--server.xml文件
2.将下面的代码配置到Host标签下
<Context path="/fileFile" docBase="F:\img\upload" debug="0" reloadable="true" />
3.此时项目启动后 localhost:8080/fileFile/hh.jpg 其实是访问 F:\img\upload下的图片
图片访问的问题解决了,我们来看一下,如何下载该虚拟路径的文件,原来是像用像访问图片一样,用网上很多的方法js下载文件,但是发现js不能下载txt、pdf等格式,所以还是选择用java来下载。
B 下载虚拟路径下的文件
下面贴上步骤
1. 为了方便应用的迁移以及修改,在java代码中最好不要使用绝对路径,所以就用到了配置文件,在resource
目录下新建一个fileFilePath.properties文件配置两个键值:
fileFilePath=/fileFile
fileFileRealPath=F:\\img\\upload
接下来是前台和后台的代码:
2.后台代码
(a)control层 不用到ssm框架,简单的java web用servlet也可以实现
/**
* 下载文件
* @param filename 下载的文件名 包括后缀 如.txt等
* @param response
* @throws Exception
*/
@RequestMapping(value="/fileDownload",method=RequestMethod.GET)
public void download(@RequestParam(value="filename")String filename,
HttpServletResponse response) throws Exception {
//1.读取刚才配置的fileFile.properties文件
ResourceBundle rb = ResourceBundle.getBundle("fileFilePath", Locale.getDefault());
//2.读取相对路径
String fileFilePath=rb.getString("fileFilePath");//相对路径
//2.读取绝对路径 即硬盘的存放路径
String fileFileRealPath=rb.getString("fileFileRealPath");//硬盘存放路径
FileDownload.fileDownload(response, fileFileRealPath+"\\"+filename, filename);
}
(2)所用到的 FileDownload代码如下:
public class fileDownload {
public static void fileDownload(final HttpServletResponse response, String filePath, String fileName) throws Exception{
byte[] data = toByteArray2(filePath);
fileName = URLEncoder.encode(fileName, "UTF-8");
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream;charset=UTF-8");
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
outputStream.write(data);
outputStream.flush();
outputStream.close();
response.flushBuffer();
}
/**
* 读取到字节数组
*
* @param filePath
* @return
* @throws IOException
*/
public static byte[] toByteArray2(String filePath) throws IOException {
File f = new File(filePath);
if (!f.exists()) {
throw new FileNotFoundException(filePath);
}
FileChannel channel = null;
FileInputStream fs = null;
try {
fs = new FileInputStream(f);
channel = fs.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
while ((channel.read(byteBuffer)) > 0) {
}
return byteBuffer.array();
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.前台 通过点击按钮触发函数,触发的函数如下,需要将文件名传递过去
function filedownload(filename) {
window.location.href='<%=basePath%>/fileDownload.do?filename='+filename;
}
注意这里需要用window.location.href来访问后台接口。
总结:其实下载本地文件成功之后,部署到服务器上是一样的效果。
参考链接:
https://panyongzheng.iteye.com/blog/2067554