前台+后台 java下载服务器、本地文件(下载tomcat配置的虚拟路径下文件)指定任意保存路径,可以用于SSM框架

背景:java web网站与APP项目共同部署在服务器上,APP有一个上传图片、文件的功能,网站需要查看下载APP上传的图片。

这时候需要考虑遇到一个问题:APP将文件上传到服务器上并且上传到的是项目内的地址是没问题的,但是因为重新部署或Tomcat突然犯抽导致需要重装什么的,以前上传的图片和文件可能会丢失。所以可以将文件和图片上传到项目外,可以采用配置Tomcat的虚拟路径。同时还要解决的是文件下载问题。

A 首先看一下虚拟路径的配置以及图片访问

1.采用配置Tomcat的虚拟路径, 打开  tomcat文件夹下--conf文件夹--server.xml文件

前台+后台 java下载服务器、本地文件(下载tomcat配置的虚拟路径下文件)指定任意保存路径,可以用于SSM框架

 2.将下面的代码配置到Host标签下

<Context path="/fileFile"  docBase="F:\img\upload" debug="0" reloadable="true" />

前台+后台 java下载服务器、本地文件(下载tomcat配置的虚拟路径下文件)指定任意保存路径,可以用于SSM框架

 

3.此时项目启动后 localhost:8080/fileFile/hh.jpg  其实是访问 F:\img\upload下的图片

 

图片访问的问题解决了,我们来看一下,如何下载该虚拟路径的文件,原来是像用像访问图片一样,用网上很多的方法js下载文件,但是发现js不能下载txt、pdf等格式,所以还是选择用java来下载。

 

B 下载虚拟路径下的文件

下面贴上步骤

1. 为了方便应用的迁移以及修改,在java代码中最好不要使用绝对路径,所以就用到了配置文件,在resource

前台+后台 java下载服务器、本地文件(下载tomcat配置的虚拟路径下文件)指定任意保存路径,可以用于SSM框架目录下新建一个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