文件上传与下载_下载校验文件,并根据说明文档要求将文件上传至服务器指定目录 - CSDN
精华内容
参与话题
  • javaweb文件上传与下载

    万次阅读 热门讨论 2018-08-24 14:42:18
    一、文件上传 要实现Web开发的上传功能,通常需要完成两步操作:一是在Web页面中添加上传输入项;二是在Servlet中读取上传文件的数据,并保存到本地硬盘中。 上传大多数情况是通过表单的形式提交给服务器,使用&...

    一、文件上传

    要实现Web开发的上传功能,通常需要完成两步操作:一是在Web页面中添加上传输入项;二是在Servlet中读取上传文件的数据,并保存到本地硬盘中。

    上传大多数情况是通过表单的形式提交给服务器,使用<input type="file">标签。

    使用<input type="file">标签需要注意以下两点:

    1.必须设置name属性,不然浏览器不会发送上传文件的数据。

    2.必须将method属性设置为postectype属性设置为“multipart/form-data”类型。

    由于在Servlet直接读取上传数据,并且解析出相应文件数据是一项非常麻烦的工作。为了方便处理上传数据,Apache组织提供了一个开源组件Commons-FileUpload。该组件可以将“multipart/form-data”类型请求的各种表单域解析出来,并实现一个或多个文件上传,同时也可以限制上传文件的大小等内容。其性能十分优异,使用极其简单。

    那么,下面就来看一个实例。

    首先,创建一个Web项目,导入开源组件Commons-FileUpload的两个jar包,commons-fileupload-1.3.3.jar,commons-io-2.6.jar。

    链接:https://download.csdn.net/download/cc1969281777/10623929

    创建上传页面upload.html:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>文件上传</title>
    </head>
    <body>
    <!--表单的enctype属性要设置为multipart/form-data-->
    <form action="UploadServlet" method="post" enctype="multipart/form-data">
        <table width="600">
            <tr>
                <td>上传者</td>
                <td><input type="text" name="name"/></td>
            </tr>
            <tr>
                <td>上传文件</td>
                <td><input type="file" name="myfile"/></td>
            </tr>
            <tr>
                <!--设置单元格可横跨的列数。-->
                <td colspan="2"><input type="submit" value="上传"/></td>
            </tr>
        </table>
    
    </form>
    </body>
    </html>

    创建Servlet:

    package cn.itcast.fileupload;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.List;
    import java.util.UUID;
    /**
     * Created by lc on 2018/8/24.
     */
    @WebServlet(name = "UploadServlet",urlPatterns = "/UploadServlet")
    public class UploadSevlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request,response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            try{
                response.setContentType("text/html;charset=utf-8");
    //            创建DiskFileItemFactory工厂对象
                DiskFileItemFactory factory=new DiskFileItemFactory();
    //            设置文件缓存目录,如果该文件夹不存在则创建一个
                File f=new File("S:\\TempFolder");
                if (!f.exists()){
                    f.mkdirs();
                }
                factory.setRepository(f);
    //            创建ServletFileUpload对象
                ServletFileUpload fileUpload=new ServletFileUpload(factory);
    //            设置字符编码
                fileUpload.setHeaderEncoding("utf-8");
    //            解析request,将form表单的各个字段封装为FileItem对象
                List<FileItem> fileItems = fileUpload.parseRequest(request);
    //            获取字符流
                PrintWriter writer=response.getWriter();
    //            遍历List集合
                for (FileItem fileItem:fileItems) {
    //            判断是否为普通字段
                    if (fileItem.isFormField()){
    //                    获取字段名称
                        String name = fileItem.getFieldName();
                        if(name.equals("name")){
    //                        如果字段值不为空
                            if (!fileItem.getString().equals("")){
                                String value=fileItem.getString("utf-8");
                                writer.print("上传者:"+value+"<br />");
                            }
                        }
                    }
                    else {
                        //获取上传的文件名
                        String filename=fileItem.getName();
    //                    处理上传文件
                        if(filename!=null&&filename!=""){
                            writer.print("上传的文件名称是:"+filename+"<br />");
    //                        保持文件名唯一
                            filename= UUID.randomUUID().toString()+"_"+filename;
                            String webpath="/upload/";
    //                        创建文件路径
                            String filepath=getServletContext().getRealPath(webpath+filename);
                            //创建File对象
                            File file=new File(filepath);
                            //创建文件夹
                            file.getParentFile().mkdirs();
                            //创建文件
                            file.createNewFile();
                            //获取上传文件流
                            InputStream in=fileItem.getInputStream();
    //                        使用 FileOutputStream打开服务器端的上传文件
                            FileOutputStream out=new FileOutputStream(file);
    //                        流的对拷
                            byte[] bytes=new byte[1024];//每次读取一个字节
                            int len;
    //                        开始读取上传文件的字节,并将其输出到服务器端的上传文件输出流中
                            while ((len=in.read(bytes))>0)
                                out.write(bytes,0,len);
                            in.close();
                            out.close();
                            fileItem.delete();
                            writer.print("文件上传成功!");
                        }
                    }
    
    
                }
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    

     运行截图:

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    至此,文件上传功能就已经实现了。此时,进入项目发布目录,就可以看到上传的文件了,如下图:

    上传的文件

     

    二、文件下载

    1.创建下载页面download.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>文件下载</title>
    </head>
    <body>
    <a href="/Download?filename=1.jpg">文件下载</a>
    </body>
    </html>

    2.创建Servlet

    package cn.itcast.fileupload;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    /**
     * Created by lc on 2018/8/24.
     */
    @WebServlet(name = "DownloadServlet",urlPatterns = "/Download")
    public class DownloadServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request,response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            //获取文件名
            String filename = request.getParameter("filename");
            //文件所在的文件夹
            String folder="/download/";
            //通知浏览器以下载的方式打开
            response.addHeader("Content-Type","application/octet-stream");
            response.addHeader("Content-Disposition","attachment;filename="+filename);
            //通过文件输入流读取文件
            InputStream in=getServletContext().getResourceAsStream(folder+filename);
            OutputStream out=response.getOutputStream();
            byte[] bytes=new byte[1024];
            int len=0;
            while ((len=in.read(bytes))!=-1){
                out.write(bytes,0,len);
            }
        }
    }
    

     3.在项目发布目录,创建download文件夹,并且在文件夹里放置一个名为1.jpg的文件

    如下图:

    运行截图:

     

     

    展开全文
  • 文件上传下载

    千次阅读 2017-03-28 11:12:28
    什么是文件上传文件上传就是把用户的信息保存起来。为什么需要文件上传?在用户注册的时候,可能需要用户提交照片。那么这张照片就应该要进行保存。上传组件(工具)为什么我们要使用上传工具?为啥我们需要上传组件...

    什么是文件上传?

    文件上传就是把用户的信息保存起来。

    为什么需要文件上传?

    在用户注册的时候,可能需要用户提交照片。那么这张照片就应该要进行保存。

    上传组件(工具)

    为什么我们要使用上传工具?

    为啥我们需要上传组件呢?当我们要获取客户端的数据,我们一般是通过getParameter()方法来获取的。

    上传文件数据是经过MIME协议进行分割的,表单进行了二进制封装。也就是说:getParameter()无法获取得到上传文件的数据。

    我们首先来看看文件上传http是怎么把数据带过去的

    • jsp页面,表单一定要指定enctype:multipart/form-data
    
        <form action="${pageContext.request.contextPath }/servlet/UploadServlet1" enctype="multipart/form-data" method="post">
            上传用户:<input type="text" name="username"><br/>
            上传文件1:<input type="file" name="file1"><br/>
            上传文件2:<input type="file" name="file2"><br/>
            <input type="submit" value="提交">
        </form>
    
    
    • http抓包

    这里写图片描述

    • 尝试在Servlet上使用getParameter()获取数据
    
    
            String ss = request.getParameter("username");
            System.out.println(ss);
    • 直接使用getParameter是获取不到数据的。

    这里写图片描述

    那么我们要怎么办呢????request对象提供了ServletInputStream流给我们读取数据

    • 我们试着读取下文件
    
            ServletInputStream inputStream = request.getInputStream();
    
            byte[] bytes = new byte[1024];
            int len = 0;
    
            while ((len = inputStream.read(bytes)) > 0) {
                System.out.println(new String(bytes, 0, len));
            }
    
    • 在jsp页面多增添一个input控件
    
    <input type="text" name="password">
    
    • 我上传的文本文件内容就是111111,读取效果如下:

    这里写图片描述

    现在我们能够读取上传文件的数据了,但是现在问题又来了:怎么把文件上传个数据和普通传送给服务器的数据分割开来呢???上面在图上我们已经看到了,他们是混合在一起的。

    按我们平常的做法是很难分割开来的,所以我们需要上传组件


    上传组件有两种

    • FileUpload【操作比较复杂】
    • SamrtUpload【操作比较简单】

    FileUpload

    要使用FileUpload组件,就需要导入两个jar包

    • commons-io
    • Commons-fileupload

    开发步骤

    • 创建解析器工厂对象【DiskFileItemFactory】
    • 通过解析器工厂创建解析器【ServletFileUpload】
    • 调用解析器方法解析request对象,得到所有上传的内容【list】
    • 遍历list,判断每个对象是否是上传文件
      • 如果是普通表单字段,得到字段名和字段值
      • 如果是上传文件,调用InputSteam方法得到输入流,读取上传的数据

    快速入门

    
    
            try{
    
                //1.得到解析器工厂
                DiskFileItemFactory factory = new DiskFileItemFactory();
    
                //2.得到解析器
                ServletFileUpload upload = new ServletFileUpload(factory);
    
                //3.判断上传表单的类型
                if(!upload.isMultipartContent(request)){
                    //上传表单为普通表单,则按照传统方式获取数据即可
                    return;
                }
    
                //为上传表单,则调用解析器解析上传数据
                List<FileItem> list = upload.parseRequest(request);  //FileItem
    
                //遍历list,得到用于封装第一个上传输入项数据fileItem对象
                for(FileItem item : list){
    
                    if(item.isFormField()){
                        //得到的是普通输入项
                        String name = item.getFieldName();  //得到输入项的名称
                        String value = item.getString();
                        System.out.println(name + "=" + value);
                    }else{
                        //得到上传输入项
                        String filename = item.getName();  //得到上传文件名  C:\Documents and Settings\ThinkPad\桌面\1.txt
                        filename = filename.substring(filename.lastIndexOf("\\")+1);
                        InputStream in = item.getInputStream();   //得到上传数据
                        int len = 0;
                        byte buffer[]= new byte[1024];
    
    
                        String savepath = this.getServletContext().getRealPath("/upload");
                        FileOutputStream out = new FileOutputStream(savepath + "\\" + filename);  //向upload目录中写入文件
                        while((len=in.read(buffer))>0){
                            out.write(buffer, 0, len);
                        }
    
                        in.close();
                        out.close();
                    }
                }
    
            }catch (Exception e) {
                e.printStackTrace();
            }

    测试

    • 普通的字段和上传的文件都能读取得到了!

    这里写图片描述


    SmartUpload

    要使用SmartUpload组件,就需要导入smartupload.jar开发包

    快速入门

    
    
            //实例化组件
            SmartUpload smartUpload = new SmartUpload();
    
            //初始化上传操作
            smartUpload.initialize(this.getServletConfig(), request, response);
    
    
            try {
    
                //上传准备
                smartUpload.upload();
    
                //对于普通数据,单纯到request对象是无法获取得到提交参数的。也是需要依赖smartUpload
                String password = smartUpload.getRequest().getParameter("password");
                System.out.println(password);
    
                //上传到uploadFile文件夹中
                smartUpload.save("uploadFile");
    
    
            } catch (SmartUploadException e) {
                e.printStackTrace();
            }
    

    测试

    同样地,我们可以上传文件到uploadFile文件夹中。代码量也的确减少很多!

    也能够获取普通字段的参数

    这里写图片描述


    上传文件名的中文乱码和上传数据的中文乱码

    • 我把文件名改成中文,就乱码了

    这里写图片描述

    • 表单提交过来的中文数据也乱码了

    这里写图片描述

    上面已经说了,上传文件的数据的表单进行了二进制封装,所以使用request对数据编码编码,对于表单提交过来的数据是不奏效的!

    FileUpload解决乱码

    使用FileUpload解决乱码问题是十分简单的

    • 解决中文文件名乱码,得到解析器以后,就直接设置解析器的编码为UTF-8就行了!
    
    
            //设置upload的编码
            fileUpload.setHeaderEncoding("UTF-8");
    
    • 解决表单数据乱码,在获取表单值的时候,按照UTF-8编码来获取
    
       String value = fileItem.getString("UTF-8");

    效果:

    这里写图片描述


    SmartUpload解决乱码

    这个组件解决乱码问题有点麻烦,在网上找了各种办法也没找到简单的……

    所以,如果数据不涉及到中文就使用SmartUpload组件,涉及到中文数据就使用FileUpload组件吧!


    多个文件上传,动态添加上传控件

    假设我现在有多个文件要上传,而且要上传的个数是不确定的。那么我们要怎么办呢???

    我们不可能列出很多很多个上传文件的控件在页面上,这样不美观。如果用户用不到那么多个控件,也浪费呀。

    所以,我们想要动态地增添上传文件的控件,如果用户还想要上传文件,只需要动态地生成控件出来即可!

    分析

    要想在页面上动态地生成控件,无非就是使用JavaScript代码。

    那么我们要怎么做呢??

    这样子吧:当用户想要上传文件的时候,就点击按钮,按钮绑定事件,生成文件上传的控件

    为了做得更加完善,每当生成了文件上传的控件,也提供一个删除按钮,删除该控件!

    我们应该使用div装载着我们要生成的控件和删除按钮,而用户点击删除的时候,应该是要把删除按钮和文件上传控件都一起隐藏起来的。所以,最好就是使用嵌套div

    代码

    • 页面代码:
    
    
    <table border="1px">
    
        <tr>
            <td>上传用户:</td>
            <td><input type="text" name="username"></td>
        </tr>
    
        <tr>
            <td>添加上传文件</td>
            <td><input type="button" value="添加上传文件" onclick="addUploadFile()"> </td>
        </tr>
    
        <tr>
    
            <td>
                <div id="file">
                </div>
            </td>
        </tr>
    
    </table>
    
    • javaScript代码
    
        <script type="text/javascript">
    
            function addUploadFile() {
    
                //生成文件上传控件
                var input = document.createElement("input");
                input.type = 'file';
                input.name = 'fileName';
    
    
                //生成删除按钮
                var del = document.createElement("input");
                del.type = 'button';
                del.value = '删除';
    
                //生成内部的div
                var innerDiv = document.createElement("div");
    
                //将两个控件绑定到内部div上
                innerDiv.appendChild(input);
                innerDiv.appendChild(del);
    
                //得到外部div控件,并将内部div绑定到外部div上
                var outterDiv = document.getElementById("file");
                outterDiv.appendChild(innerDiv);
    
                //为删除按钮绑定事件
                del.onclick = function dele() {
    
                    //调用外界div的remove方法把内部的div干掉
                    this.parentNode.parentNode.removeChild(this.parentNode);
                }
    
            }
    
        </script>
    

    文件上传细节

    • 如果上传文件的大小大于我们设定文件的大小,那么文件在上传的时候会使用临时文件保存上传数据。在上传完毕后,我们应该删除临时文件
    • 上传文件的位置是不能在WEB服务器管理之下的,否则可能造成安全问题【其他人有可能通过手段来修改上传文件】
    • 如果上传文件名相同,那么就会把原本的上传文件覆盖掉。我们要生成一个独一无二的文件名。
    • 如果用户量很大,上传文件非常多。那么我们不应该在一个目录保存所有的上传文件,这样很可能造成磁盘奔溃了。所以我们要把上传的文件打散到不同的目录下

    分析

    删除临时文件问题是非常简单的,只需要在所有的操作完毕之后,调用FileItem的delete()方法即可

    让上传文件的位置不能在WEB服务器管理之下,我们把上传文件的位置放到WEB-INF/目录下即可!

    文件名相同的问题,我们可以使用UUID+用户上传的文件名来作为我们保存上传文件名。这样的文件名就是独一无二的了。

    要将上传的文件进行打散,那么我们需要使用HashCode算法来进行打散

    • 低四位生成一级目录
    • 5-8位生成二级目录

    代码

    下面我们写一个比较完善的上传文件代码

    • 使用hashCode算法来打散保存的目录
    
        private String makeDirPath(String fileName, String path) {
    
            //通过文件名来算出一级目录和二级目录
            int hashCode = fileName.hashCode();
            int dir1 = hashCode & 0xf;
            int dir2 = (hashCode & 0xf0) >> 4;
    
            String dir = path + "\\" + dir1 + "\\" + dir2;
    
            //如果该目录不存在,就创建目录
            File file = new File(dir);
            if (!file.exists()) {
    
                file.mkdirs();
            }
            //返回全路径
            return dir;
    
        }
    
    
    • 生成独一无二的文件名
    
    
        private String makeFileName(String fileName) {
    
            //使用下划线把UUID和文件名分割开来,后面可能会解析文件名的。
            return UUID.randomUUID().toString() + "_"+ fileName;
    
        }
    • 上传的代码
    
    
            //创建工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
    
            //通过工厂创建解析器
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
    
            //设置upload的编码
            fileUpload.setHeaderEncoding("UTF-8");
    
            //判断上传表单的类型
            if(!fileUpload.isMultipartContent(request)){
                //上传表单为普通表单,则按照传统方式获取数据即可
                return;
            }
    
            try {
    
                //解析request对象,得到List【装载着上传的全部内容】
                List<FileItem> list = fileUpload.parseRequest(request);
    
                //遍历List,判断装载的内容是普通字段还是上传文件
                for (FileItem fileItem : list) {
    
                    //如果是普通输入项
                    if (fileItem.isFormField()) {
    
                        //得到输入项的名称和值
                        String name = fileItem.getFieldName();
                        String value = fileItem.getString("UTF-8");
    
                        System.out.println(name + " = " + value);
                    } else {
    
                        //如果是上传文件
    
                        //得到上传名称【包括路径名】
                        String fileName = fileItem.getName();
    
                        //截取文件名
                        fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
    
                        //生成独一无二的文件名
                        fileName = makeFileName(fileName);
    
                        InputStream inputStream = fileItem.getInputStream();
    
                        //得到项目的路径,把上传文件写到项目中
                        String path = this.getServletContext().getRealPath("/WEB-INF/uploadFile");
    
                        //得到分散后的目录路径
                        String realPath = makeDirPath(fileName, path);
    
                        FileOutputStream outputStream = new FileOutputStream(realPath + "\\" + fileName);
    
                        byte[] bytes = new byte[1024];
                        int len = 0;
                        while ((len = inputStream.read(bytes)) > 0) {
                            outputStream.write(bytes, 0, len);
                        }
    
                        inputStream.close();
                        outputStream.close();
    
                        //删除临时文件的数据
                        fileItem.delete();
    
                    }
                }
    
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
    

    效果:

    • 成功把目录打散,文件名也是独一无二的了。

    这里写图片描述


    列出上传目录下的文件,提供下载

    在讲解respose对象的时候已经讲解过文件下载了。这次我们就直接写一个小案例来巩固文件下载把。

    • 上传目录下的文件有3个

    这里写图片描述

    分析

    首先,要把目录下的文件都列出来。由于后面要根据文件名对文件进行下载,所以我们用一个Map集合来保存所有的文件

    下载文件部分也很简单,根据文件名和上传文件位置找到对应的文件,对其进行读写,然后修改消息头实现下载就好了。

    代码

    • 将存放在WEB-INF/目录下的文件全部放在Map集合中
    
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
            //得到上传文件的目录
            String filePath = this.getServletContext().getRealPath("/WEB-INF/uploadFile");
    
            Map map = new HashMap();
    
            //使用递归来得到所有的文件,并添加到Map集合中
            getAllFiles(new File(filePath), map);
    
            request.setAttribute("map", map);
            request.getRequestDispatcher("/listFile.jsp").forward(request, response);
    
    
    
        }
    
        private void getAllFiles(File filePath, Map map) {
    
            //如果不是文件,那么它就是文件夹
            if (!filePath.isFile()) {
    
                //列出文件夹下所有的文件(可能是文件,可能是文件夹)
                File[] files = filePath.listFiles();
                for (File file : files) {
    
                    //得到的文件(或者是文件夹)再对其进行判断
                    getAllFiles(file, map);
                }
            } else {
                //进入到else语句了,肯定是文件了
    
                //得到文件名
                String fileName = filePath.getName().substring(filePath.getName().lastIndexOf("_") + 1);
    
                //我们将文件全名作为key,文件名作为value保存在map集合中
                map.put(filePath.getName(), fileName);
    
            }
    
        }
    
    • 在JSP页面中显示可以下载的文件
    
    
    
    <c:forEach items="${map}" var="me">
    
        <c:url var="url" value="/DownFileServlet">
            <c:param name="fileName" value="${me.key}"></c:param>
        </c:url>
        ${me.value}<a href="${url}">下载!</a><br>
    
    </c:forEach>
    • 实现下载的Servlet
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            //得到文件的全名
            String fileName = request.getParameter("fileName");
    
            //如果是中文数据,需要转码。
            fileName = new String(fileName.getBytes("ISO8859-1"), "utf-8");
    
            //得到保存文件的位置
            String path = this.getServletContext().getRealPath("/WEB-INF/uploadFile");
    
            //文件是通过文件名进行hashCode打散保存的,通过文件名拿到文件绝对路径
            String fileRealPath = makeFilePath(fileName, path);
            System.out.println(fileRealPath);
    
            //判断文件是否存在
            File file = new File(fileRealPath);
            if (!file.exists()) {
                request.setAttribute("message", "您要下载的资源不存在了!");
                request.getRequestDispatcher("/message.jsp").forward(request, response);
                return ;
            }
    
            //存在
    
            //读取该文件并把数据写给浏览器
            FileInputStream inputStream = new FileInputStream(fileRealPath);
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(bytes)) > 0) {
                response.getOutputStream().write(bytes, 0, len);
            }
    
            inputStream.close();
    
    
            //设置消息头,告诉浏览器,这是下载的文件
            String name = fileName.substring(fileName.lastIndexOf("_") + 1);
            response.setHeader("content-disposition","attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
    
        }
    
        private String makeFilePath(String fileName, String path) {
    
            int hashCode = fileName.hashCode();
    
            int dir1 = hashCode & 0xf;
            int dir2 = (hashCode & 0xf0) >> 4;
    
            String dir = path + "\\" + dir1 + "\\" + dir2 +"\\"+ fileName;
            return dir;
        }
    

    效果

    这里写图片描述

    展开全文
  • 文件上传下载两种方式

    千次阅读 2018-09-02 17:09:40
    文件上传下载 上传 一,借助三方工具类实现上传文件 二,用springmvc框架中的类– 不过需要在springmvc.xml中配置上传文件解析器 下载 下载都是一样的,两个流,一个头 两个流:需要读取服务器端本地硬盘到内存...

    文件的上传和下载

    上传
    一,借助三方工具类实现上传文件
    二,用springmvc框架中的类– 不过需要在springmvc.xml中配置上传文件解析器
    下载
    下载都是一样的,两个流,一个头
    两个流:需要读取服务器端本地硬盘到内存的输入流,另一个是从服务器内存到客户端的输出流
    一个头:设置下载的响应头



    需要jar包:
    commons-fileupload-1.3.1.jar
    commons-io-2.2.jar


    正文

    在通过表单上传文件时,需要注意以下几点
    1,post请求
    2,输入框类型设置为file
    3,把表单中属性修改 enctype=’multipart/form-data’多部件类型
    该表单属性默认为 application/x-www-form-urlencoded,所以需要修改

      <!-- 测试文件上传和下载 -->
     <form action="${pageContext.request.contextPath}/file/FileUploadServlet" 
             method="post" enctype="multipart/form-data">
                     <p>用户名:<input type="text" name="uname" /> </p>
                     <p>密码:<input type="password" name="pwd" /> </p>
                     <p>照片:<input type="file" name="photo" /> </p>
                     <p> <input type="submit" value="注册"> </p>
     </form>
    Servlet部分

    在服务器端 webapp下首先创建一个upload文件夹,用来存放上传的文件,需要考虑上传文件的重名问题
    两种解决方案:
    1,把上传的文件放到upload下的不同文件夹下(可以通过获取系统的毫秒值来命名)
    2,把上传的文件重新命名(通过UUID类生成的随机字符命名)
    这里采用第二种方式

          public void doPost(HttpServletRequest request,
      HttpServletResponse response) throws ServletException, IOException {
    
            /*  String uname = request.getParameter("uname");
              String password= request.getParameter("pwd");
              String photo=request.getParameter("photo");*/
    
            /*  user.setName(uname);
              user.setPassword(password);
              System.out.println(user);*/
    
              //借助其他三方工具jar包
              //1,创建对象,创建保存字符串的临时文件及保存位置
               DiskFileItemFactory factory=new DiskFileItemFactory();
               //2,
               ServletFileUpload upload=new ServletFileUpload(factory);
               //创建一个user对象,封装信息
               User user=new User();
                //3,从字符串获取内容  分两步, 普通键值对 和 文件信息
                   try {
                    List<FileItem> items = upload.parseRequest(request);
                     //4,遍历集合,获取普通键值对信息
    
                    for(FileItem item :items) {
                         //获取键名
                        String fileName=item.getFieldName();
    
                        //判断是普通键值对信息
                        if(item.isFormField()) {
                          if("uname".equals(fileName)){
                                  user.setName(item.getString());
                              }
                              if("password".equals(fileName)){
                                  user.setPassword(item.getString());
                              }
                        }else {
                            //文件信息
                        //5,解决重名问题,生成随机字符串,采用随机字符+ 文件原名=新文件名
                             String uuid=UUID.randomUUID().toString();
    
                              //去掉uuid生成的随机字符中的 -, 以空串代替,实现去除
                             uuid=uuid.replace("-", "");
                          //获取原文件名,
                             String oldFileName=item.ge虑tName();
               //考存带有路径的问题,做判断,有则截取,这里\需要转义,所以用\\
                 int  index=  oldFileName.lastIndexOf("\\");
         //判断\路径分隔符的位置,如果为-1,则没有,如果有,则截取后面的文件名部分
                                  if(index!=-1){
                                      //有路径,则从后一位截取,获取文件名和后缀名
                               oldFileName.substring(index+1); 
                                  }
                            //拼接新文件名
                             String newFileName=uuid+"-"+oldFileName;
        //6,获取upload的文件夹路径 ,这里相对于项目的路径,web项目也可说是相对于classes目录
        String path= request.getServletContext().getRealPath("/upload");
    
                            //创建文件对象,指定文件夹下,文件名
                           File file=new File(path,newFileName);
    
    
                      //7,把文件信息写入到指定文件
                          item.write(file);
                        }
                    }
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
        }

    下载

    主要是通过response响应对象的输出流响应给对象

        //下载功能
        protected void download(HttpServletRequest request,
         HttpServletResponse response) throws ServletException, IOException {
                   //一个头,两个流
    
               //1,获取前台传过来的文件名
                String fileName= request.getParameter("fileName");
                //响应头 --固定格式  这里变量拼接,因此要转义filename后双引号     
      response.addHeader("content-Disposition", "attachment;filename=\""+fileName+"\"");
    
             //获取该文件在服务器端的资源路径,因为是从服务器下载文件 
                String path=request.getServletContext().getRealPath("/upload");
                 //创建该下载文件的文件对象
                 File file=new File(path,fileName);
               //2一个输入流,从服务器硬盘到内存
            BufferedInputStream  bis=new BufferedInputStream(new FileInputStream(file));
    
      //3,一个输出流,从服务器端内存到客户端,这里是多态,因OutputStream是接口,
      //父类引用指向子类对象,实现动态绑定
                OutputStream sos = response.getOutputStream();
    
                int len=-1;
                byte[] b=new byte[1024];
                while((len=bis.read(b))!=-1) {
                    sos.write(b,0,len);
                }
                sos.close();
                bis.close();
        }

    springmvc中实现上传

    1,配置文件

    <!-- 配置上传文件的解析器 -->
        <!-- 实现上传时,这个解析器的id是固定名称multipartResolver -->
        <bean id="multipartResolver" 
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 上传文件的大小设置,上传文件的大小不能超过参数的指定值,值单位是B,
    这里设置的是10M,value中不可以用运算符,为了图方便,直接乘会报错(试过!) -->
            <property name="maxUploadSize" value="10485760"></property>
            <!-- 上传文件的默认编码格式 -->
            <property name="defaultEncoding" value="utf-8"></property>
            <!-- 类似懒加载的属性.可以定义该属性.让解析文件的时候再抛异常 -->
            <property name="resolveLazily" value="true"></property>
        </bean>

    2,conroller中
    这里对于上传文件的命名采用的是2者的组合方式,既创建文件夹,又修改文件名方式

    /*这里要注意在前台表单中上传文件中input输入框的名字要和这里形参的MultipartFile的的一致,
     才能实现匹配,获取上传数据*/
         @RequestMapping("/user_upload.do") 
        public String fileUpload(User user,MultipartFile photo_str,
        HttpServletRequest request,Model model) throws IllegalStateException, IOException{
              //1,接收普通数据 user
              //user这里只是接收表单中其他数据,将其封装到user类中的,方便处理数据
    
              //2,接收文件数据      ,文件存储位置, 解决文件重名问题
    
              if(photo_str!=null) {
              //也得先在webapp下创建一个upload文件夹, 获取到upload位置,
           //当然也可以配置tomcat的虚拟路径,直接存储到tomcat服务器中,这里是存储到项目中的
    String path = request.getSession().getServletContext().getRealPath("/upload"); 
              //获取旧文件名
              String oldname = photo_str.getOriginalFilename();
              //获取后缀名,最后一个.的下标
               int index = oldname.lastIndexOf(".");
               //截取,只获取 .后缀名 部分
               String exname = oldname.substring(index);
               //生成新的文件名
              String uuid = UUID.randomUUID().toString().replace("-","");
               //文件名和后缀拼接成新的文件名
               String  newName=uuid+exname;
    
                 //获取系统的当前毫秒值,用来做文件夹的名字
              long ms=System.currentTimeMillis();
               //和upload的绝对路径拼接,形成一个upload文件夹下的完整文件路径
               path=path+"/"+ms;
    
              //根据路径创建文件对象 -- 
               File file=new File(path);
               //创建文件夹,先判断是否存在,理论上是不会存在的
               if(!file.exists()) {
                   file.mkdirs();
               }
               //创建文件夹下文件
                file=new File(path,newName);
    
                //将上传照片写入文件
                photo_str.transferTo(file);
    
                //user对象只是封装的图片的完整路径
                user.setPhoto(file.getPath());
              }
         }
    springmvc中实现下载
    //文件下载
         @RequestMapping("/user_fileDownload.do") 
         public String fileDownload(String fileName,
    HttpServletResponse reponse,HttpServletRequest request) throws IOException{
             //一个头,两个流
             InputStream is=null;
             OutputStream os=null;
                //首先还是获取upload目录下的文件名路径
             String path = request.getSession().getServletContext().getRealPath("/upload/"+fileName);
              //根据获取的路径,读入文件到内存中
              //从服务器端本地读入文件流
     is=new BufferedInputStream(new FileInputStream(path)); 
     //解决文件名在下载时遇到中文出现乱码问题----反向编码一次
        //注意这个编码要在文件读取文件到输入流中之后,不然把文件名先改变编码后,
       //在服务器端根据路径去读文件到输入流,会找不到这个文件,因为编码方式不同,文件名就变了,会报错
             fileName =new String(fileName.getBytes("utf-8"),"iso8859-1");
             reponse.addHeader("content-Disposition", "attachment;fileName="+fileName);
             byte[] b=new byte[1024];
             os=reponse.getOutputStream(); //写出到客户端的写出流
    
             int len=-1;
             while((len=is.read(b))!=-1){
                 os.write(b, 0, len);
             } 
             os.close();
             is.close();
    
         }



    学习总结,水平有限,如有错误,敬请指正,感激不尽!

    展开全文
  • java实现文件上传与下载

    万次阅读 2019-12-13 14:49:54
    JAVA中文件上传下载知识点整理, 东风化宇,文件上传 一、对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦。 JSP...

    欢迎大家访问我的博客:地址

     

    感谢:孤傲苍狼,JavaWeb学习总结(五十)——文件上传和下载

               JAVA中文件上传下载知识点整理

               东风化宇,文件上传

    一、对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦。

     

    JSP代码,POST请求,表单必须设置为enctype="multipart/form-data"

    <span style="font-size:14px;"><form action="upload3" method="post" enctype="multipart/form-data">
                File to upload:<input type="file" name="upfile"><br><br> 
                <input type="submit" value="Press"> to upload the file!
    </form></span>

    Servlet代码:

     

    <span style="font-size:14px;"><span style="white-space:pre">	</span>protected void doGet(HttpServletRequest request,
    			HttpServletResponse response) throws ServletException, IOException {
    		request.setCharacterEncoding("UTF-8");
    		System.out.println("请求正文长度为--->" + request.getContentLength());
    		System.out.println("请求类型及表单域分割符--->" + request.getContentType());
    		//保存文件目录
    		String savePath = "d:/temptemp";
    		File file = new File(savePath);
    		//判断上传文件目录是否存在
    		if(!file.exists() && !file.isDirectory()){
    			//此目录不存在
    			file.mkdir();
    		}
    		
    		String message = "";
    		try {
    			InputStream is = request.getInputStream();
    			OutputStream os = new FileOutputStream(savePath + "/test.txt");
    			
    			byte[] buffer = new byte[1024];
    			int len = 0;
    			
    			while((len=is.read(buffer))>0){
    				os.write(buffer,0,len);
    			}
    			is.close();
    			os.close();
    			message = "文件上传成功";
    		} catch (Exception e) {
    			message = "文件上传失败";
    			e.printStackTrace();
    		}
    		request.setAttribute("message", message);
    		request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request, response);
    	}</span>


    对于fireFox浏览器:

     

    上传表单为空时,request.getContentLength()为198

    上传文件时,请求头信息为:

     

    后台输出:

     

    生成的上传文件:

    注意:上传的文本的字符编码,否则filename或正文就会出现乱码的可能。

    对于chrome浏览器:

    上传表单为空时:request.getContentLength()为190

    上传文件时,请求头信息为:

    后台输出:

    生成的文件:

    以上是采用servlet接收客户端请求的方式来处理普通文本类型的文件的。虽然可以通过分隔符以及其余的一些固定的字符串如filename,通过字符串操作来获取请求正文中需要的数据,但是操作过程也仅限于文本类型,毕竟对于数据流的解析是比较麻烦的。

    二、采用Apache提供的用来处理文件上传的开源组件Commons-fileupload

    文件上传时,enctype属性必须设置为”multipart/data-form”。该属性指定了提交表单时请求正文的MIME类型,默认值为application/x-www-form-urlencoded。

    JSP代码:

     

    <span style="font-size:14px;"><form action="upload2" method="post" enctype="multipart/form-data">
                File to upload:<input type="file" name="upfile"><br><br> 
                Notes about the file:<input type="text" name="note"><br><br>
                <input type="submit" value="Press"> to upload the file!
    </form></span>

    servlet代码:

     

     

    <span style="font-size:14px;">public class FileUploadNew extends HttpServlet {
    	@Override
    	protected void doPost(HttpServletRequest request,
    			HttpServletResponse response) throws ServletException, IOException {
    		this.doGet(request, response);
    	}
    
    	@Override
    	protected void doGet(HttpServletRequest request,
    			HttpServletResponse response) throws ServletException, IOException {
    		// 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
    		String savePath = this.getServletContext().getRealPath(
    				"/WEB-INF/upload");
    		// 上传时生成的临时文件保存目录
    		String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
    		File tempFile = new File(tempPath);
    		if (!tempFile.exists() && !tempFile.isDirectory()) {
    			// 创建临时目录
    			tempFile.mkdir();
    		}
    
    		String message = "";
    		try {
    			// 1、创建一个DiskFileItemFactory工厂
    			DiskFileItemFactory factory = new DiskFileItemFactory();
    			// 设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
    			factory.setSizeThreshold(1024 * 100);// 设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
    			// 设置上传时生成的临时文件的保存目录
    			factory.setRepository(tempFile);
    			// 2、创建一个文件上传解析器
    			ServletFileUpload upload = new ServletFileUpload(factory);
    			// 监听文件上传进度
    			upload.setProgressListener(new ProgressListener() {
    				public void update(long pBytesRead, long pContentLength,
    						int arg2) {
    					System.out.println("文件大小为:" + pContentLength + ",当前已处理:"
    							+ pBytesRead);
    				}
    			});
    			// 解决上传文件名的中文乱码
    			upload.setHeaderEncoding("UTF-8");
    			// 3、判断提交上来的数据是否是上传表单的数据
    			if (!ServletFileUpload.isMultipartContent(request)) {
    				// 按照传统方式获取数据
    				return;
    			}
    
    			// 设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
    			upload.setFileSizeMax(1024 * 1024);
    			// 设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
    			upload.setSizeMax(1024 * 1024 * 10);
    			// 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
    			List<FileItem> list = upload.parseRequest(request);
    			for (FileItem item : list) {
    				// 如果fileItem中封装的是普通输入项的数据
    				if (item.isFormField()) {
    					String name = item.getFieldName();
    					// 解决普通输入项的数据的中文乱码问题
    					String value = item.getString("UTF-8");
    					// value = new String(value.getBytes("iso8859-1"),"UTF-8");
    					System.out.println(name + "=" + value);
    				} else {// 如果fileItem中封装的是上传文件
    						// 得到上传的文件名称,
    					String filename = item.getName();
    					System.out.println(filename);
    					if (filename == null || filename.trim().equals("")) {
    						continue;
    					}
    					// 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:
    					// c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
    					// 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
    					filename = filename
    							.substring(filename.lastIndexOf("\\") + 1);
    					// 得到上传文件的扩展名
    					String fileExtName = filename.substring(filename
    							.lastIndexOf(".") + 1);
    					// 如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
    					System.out.println("上传的文件的扩展名是:" + fileExtName);
    					// 获取item中的上传文件的输入流
    					InputStream in = item.getInputStream();
    					// 得到文件保存的名称
    					String saveFilename = makeFileName(filename);
    					// 得到文件的保存目录
    					String realSavePath = makePath(saveFilename, savePath);
    					// 创建一个文件输出流
    					FileOutputStream out = new FileOutputStream(realSavePath
    							+ "\\" + saveFilename);
    					// 创建一个缓冲区
    					byte buffer[] = new byte[1024];
    					// 判断输入流中的数据是否已经读完的标识
    					int len = 0;
    					// 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
    					while ((len = in.read(buffer)) > 0) {
    						// 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"
    						// + filename)当中
    						out.write(buffer, 0, len);
    					}
    					// 关闭输入流
    					in.close();
    					// 关闭输出流
    					out.close();
    					// 删除处理文件上传时生成的临时文件
    					// item.delete();
    					message = "文件上传成功!";
    				}
    			}
    		} catch (FileUploadBase.FileSizeLimitExceededException e) {
    			message = "单个文件超出最大限制";
    			e.printStackTrace();
    		} catch (FileUploadBase.SizeLimitExceededException e) {
    			message = "上传文件超出数量限制";
    			e.printStackTrace();
    		} catch (Exception e) {
    			message = "文件上传失败";
    			e.printStackTrace();
    		}
    		request.setAttribute("message", message);
    		request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,
    				response);
    	}
    
    	private String makeFileName(String filename) {
    		// 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
    		return UUID.randomUUID().toString() + "_" + filename;
    	}
    
    	/**
    	 *多目录存储
    	 */
    	private String makePath(String filename, String savePath) {
    		// 得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址
    		int hashcode = filename.hashCode();
    		int dir1 = hashcode & 0xf; // 0--15
    		int dir2 = (hashcode & 0xf0) >> 4; // 0-15
    		// 构造新的保存目录
    		String dir = savePath + "\\" + dir1 + "\\" + dir2; // upload\2\3
    															// upload\3\5
    		// File既可以代表文件也可以代表目录
    		File file = new File(dir);
    		// 如果目录不存在
    		if (!file.exists()) {
    			// 创建目录
    			file.mkdirs();
    		}
    		return dir;
    	}
    }</span>

    另:

     

    1)DiskFileItemFactory
    该工厂类用于创建FileItem的实例,对于较小的表单项,FileItem实例的内容保存在内存中,对于大的表单项,FileItem实例的内容会保存在硬盘中的一个临时文件中。大小的阈值和临时文件的路径都可以配置。构造方法如下:
    DiskFileItemFactory():文件阈值大小为10KB,默认临时文件的路径可以通过System.getProperty(“java.io.tmpdir”) 来获得。
    DiskFileItemFactory(int sizeThreshold, File repository)
    注:处理文件上传时,自己用IO流处理,一定要在流关闭后删除临时文件。
    因此建议使用:FileItem.write(File file),会自动删除临时文件。
    2)乱码问题
    ① 普通字段的乱码
    解决办法:FileItem.getString(String charset);编码要和客户端一致。
    ② 上传的中文文件名乱码
    解决办法:request.setCharacterEncoding(“UTF-8″);编码要和客户端一致。
    3)文件重名问题
    当上传的两个文件同名时,第二个文件会覆盖掉第一个文件。
    解决方法:a.txt –> UUID_a.txt,使得存入服务器的文件名唯一。
    String fileName = item.getName();
    fileName = UUID.randomUUID().toString() + "_" + fileName;
    4)文件夹中文件过多问题
    解决思路:分目录存储。下面提供两种解决方案:
    ① 按照日期分目录存储:
    //按日期分目录存储,程序中修改storePath,形如/files/2014/08/29
    DateFormat df = new SimpleDateFormat("/yyyy/MM/dd");
    String childDir = df.format(new Date());
    //文件存放路径:位于项目根目录下的files目录,不存在则创建
    String storePath = getServletContext().getRealPath("/files"+childDir);
    ② 按照文件名的hashCode计算存储目录(推荐)
    //按文件名的hashCode分目录存储
    String childDir = mkChildDir(fileName);
    //文件存放路径:位于项目根目录下的files目录,不存在则创建
    String storePath = getServletContext().getRealPath("/files"+childDir);

    <span style="font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:12px;">private String mkChildDir(String fileName) {
        int hashCode = fileName.hashCode();
        int dir1 = hashCode & 0xf;//取hashCode低4位
        int dir2 = (hashCode & 0xf0) >> 4; //取hashCode的低5~8位
        return "/" + dir1 + "/" + dir2;
    }</span>

    5)限制上传文件的大小和类型
    有时候需要对用户上传的文件大小和类型作出限制,如上传头像、证件照时不会很大,且文件MIME类型均为image/*,此时需要在服务器端进行判断。
    ① 限制大小
    单文件大小:ServletFileUpload.setFileSizeMax(2*1024*1024); //限制单文件大小为2M
    总文件大小(多文件上传):ServletFileUpload.setSizeMax(6*1024*1024);
    ② 限制类型
    一般判断:根据文件扩展名进行判断,缺点是如果更改了扩展名,如a.txt –> a.jpg,这种方法是无法检测出来的。
    稍微高级点的:根据文件MIME类型进行判断,缺点是只对IE浏览器有效,对Chrome、FireFox无效,因为后者请求头中文件的MIME类型就是依据扩展名的。
    6)服务器安全问题
    假设用户知道你的上传目录,并上传了一个含有Runtime.getRuntime().exec(“xxx”);脚本的JSP文件,就会严重威胁服务器的安全。
    解决方法:把存放文件的目录,放到WEB-INF下面。
    三、文件下载

     

    1.列出所有文件

    java代码

     

    <span style="font-size:14px;">/**
     * 列出文件目录下的所有文件
     */
    public class ListAllFile extends HttpServlet{
    	private static final long serialVersionUID = 1L;
    	@Override
    	protected void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		this.doGet(request, response);
    	}
    	@Override
    	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		//文件目录
    		String filePath = "d:/temp";
    		File file = new File(filePath);
    		
    		//存储要下载的文件
    		Map<String,String> fileMap = new HashMap<String,String>();
    		
    		//如果目录存在,并且目录是一个文件夹
    		if(file.exists() && file.isDirectory()){
    			//获取所有文件
    			this.getFiles(file,fileMap);
    		}else{
    			file.mkdir();
    		}
    		
    		//将fileMap集合发送到下载页面
    		request.setAttribute("fileMap", fileMap);
    		request.getRequestDispatcher("/WEB-INF/download.jsp").forward(request,response);
    	}
    	/**
    	 * 获取目录下的所有文件
    	 * @throws IOException 
    	 */
    	public void getFiles(File file,Map<String,String> fileMap) throws IOException{
    		//目录为文件夹
    		if(file.isDirectory()){
    			File[] files = file.listFiles();
    			//遍历数组
    			for(File f : files){
    				//递归
    				getFiles(f,fileMap);
    			}
    		}else{//文件
    			//file.getAbsolutePath()获取文件绝对路径,唯一值,如:d:\temp\aaa.txt,需要转为d:/temp/aaa.txt
    			//file.getName()获得文件名,如:aaa.txt
    			fileMap.put(file.getAbsolutePath().replace("\\","/"),file.getName());
    		}
    	}
    }
    
    </span>

    JSP代码

     

     

    <span style="font-size:14px;"><%@page import="java.net.URLEncoder"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>download</title>
    <script>
    	function myDownload(Obj,file){
    		uri = encodeURI(file);
    		Obj.href = "fileDownload?fileName="+encodeURI(uri);	//两次编码
    		Obj.click();
    	}
    </script>
    </head>
    <body>
    	<!-- 遍历Map集合 -->
    	<c:forEach items="${fileMap }" var="file">
    		${file.value } <a href="javascript:void(0)" onclick="myDownload(this,'${file.key }')">download</a>
    		<br>
    	 </c:forEach>
    	 ----------文件下载,中文乱码 -----------<br>
    	<c:forEach items="${fileMap }" var="file">
    		<c:url value="fileDownload" var="downloadUrl">
    			<c:param name="fileName" value="${file.key }"></c:param>
    		</c:url>
    		${file.value } <a href="${downloadUrl }">download</a><!-- 中文乱码 -->
    		<br>
    	</c:forEach>
    	${message}
    </body>
    </html><</span>

    2.下载文件

     

    java代码

     

    <span style="font-size:14px;">protected void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		//获取下载文件,绝对路径
    		String fileName = request.getParameter("fileName");
    		//解码
    		fileName = URLDecoder.decode(fileName, "UTF-8");
    		//文件名
    		String realName = fileName.substring(fileName.lastIndexOf("/")+1);
    		System.out.println(fileName+"--->"+realName);
    		File file = new File(fileName);
    		if(!file.exists()){
    			request.setAttribute("message", "资源已删除");
    			request.getRequestDispatcher("/WEB-INF/download.jsp").forward(request, response);
    			return;
    		}
    		//设置响应头,控制浏览器下载该文件
    		realName = new String(realName.getBytes("UTF-8"),"ISO-8859-1");
    		response.setHeader("content-disposition", "attachment;filename=" + realName);
            //response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realName, "UTF-8"));	//编码
            //读取要下载的文件,保存到文件输入流
            FileInputStream in = new FileInputStream(fileName);
            //输出流
            OutputStream out = response.getOutputStream();
            //缓冲区
            byte buffer[] = new byte[4096];
            int len = 0;
            while((len=in.read(buffer))>0){
                out.write(buffer, 0, len);
            }
            in.close();
            out.close();
    		
    }</span>

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 文件上传与下载的功能实现

    千次阅读 2018-06-22 10:12:31
     一、进行文件上传时只能使用post方式提交表单 二、表单必须添加一个属性:enctype=”multipart/form-data” 三、用于上传文件的元素必须时2、enctype属性 作用:告知服务器请求正文的MIME类型,作用content-...
  • 文件上传下载

    千次阅读 2018-05-20 16:40:05
    1.文件上传下载 HTTP请求及HTTP响应中都包含正文部分。HTTP响应的正文部分最常见的是HTML文档,此外还可以是其他任意格式的数据,如图片和声音文件中的数据。同样,HTTP请求的正文部分不仅可以是字符串格式的...
  • java实现文件上传:java实现文件下载:java实现文件删除:
  • csdn如何上传附件

    万次阅读 2018-12-12 22:24:37
    首先登陆你的csdn博客,看到首页有个下载   点击下载 进去之后点击上传资源   然后就可以上传附件了   不过他会审核两天,不要着急,过两天就发布出来了...
  • 我们知道所谓的在线编辑其实就是从服务器下载,等使用者修改完成后,再上传(回传)的这样一个过程。过程中文件下载容易实现,下载后在客户端打开编辑也容易,难一点的就在上传这一步。 但上传又可以采用http或ftp...
  • Linux(CentOS)上传下载文件方法

    万次阅读 2018-05-15 17:30:04
    Linux上传下载命令:rz,sz如果命令执行报错,先按照软件:yum -y install lrzsz 下载命令:sz输入sz加需要下载的文件名 上传命令:rz输入rz敲回车键,出现弹窗,将需要上传的文件添加到 File to send ,点OK即可...
  • 操作步骤 1. 本地建立仓库:在本地新建文件夹,右键 —&gt; TortoiseSVN —&gt; Create repository here; 2. 下载已有仓库:在本地新建文件夹,右键 —&...4. 上传本地文件:选中仓库,右键 —&gt; S...
  • 于是,就产生了用客户端程序访问SharePoint上的文档库来上传下载文件的需求。我就用C#中的WebClient类写了一个实现SharePoint上文件的上传下载的类。下面是该类的代码,里面有详细的注释。而且
  • 1.校验文件内容错误。校验文件内容一般是非HTML数据,如果下载下来的校验文件内容为HTML数据,一般为登录态过期。请重新登录小程序下载校验文件。 2.https证书过期。请确保https证书处于有效期内。 3.使用curl...
  • 文件上传下载的常用测试点

    万次阅读 2018-08-30 13:00:34
    文件上传: 页面 页面美观性、易用性(键盘和鼠标的操作、tab跳转的顺序是否正确) 按钮文字正确性 说明文字是否正确 正确/错误的提示文字是否正确 ...上传文件格式是否全部支持(图片:gif/jpg/bmp…文档:...
  • 然后一个美国同事用下面这种方式帮忙解决了多个文件上传下载的问题。 具体步骤如下: 在本地新建一个快捷方式,输入下面地址 查了一下这是运用了WebDAV,地址格式如下:\\server@SSL@port\DavWWWRoot
  • 文件上传功能测试的测试点

    万次阅读 2017-10-18 09:57:30
    文件上传功能测试的测试点 1.选择符合要求的文件上传 上传成功 2.查看下载上传成功的文件 上传文件可查看或下载 3.删除上传成功的文件 文件可删除 4.替换上传成功的文件 文件可替换 5.路径是否可以手工...
  • 如何在CSDN上上传资源

    千次阅读 2019-01-15 15:28:25
    首先登录CSDN 然后点击菜单栏顶部的下载 然后看到下载页面 有上传资源按钮 点击上传资源 就可以上传自己想要上传的资源啦
  • 4.上传文件 4.1创建文件—再开一个终端,在home/ftptest目录下创建文件haha 4.2 命令:put filename 成功上传到服务器zy的home目录下 附: 【注意】如果文件在home/ftptest/test目录下,但是连接ftp的目录...
  • Linux上传文件下载文件命令行方式

    万次阅读 多人点赞 2018-01-18 08:34:19
    在Linux主机上,安装上传下载工具包rz及sz 只需要安装下面这个包即可,执行下面的安装命令 yum install -y lrzsz 上传 在Linux命令行下输入rz, rz 输入rz命令后,会弹出对话框,选择你要上传的文件,...
  • xshell 文件上传下载

    万次阅读 2018-09-14 21:59:41
    xshell 文件上传下载 介绍两种方式:命令、工具 上传下载参照对象是本机 命令: 1.sz&nbsp; 文件下载文件大小限制 4G) 2.rz 文件上传 工具: File Transfer(工具栏中有) 这个没有上面的sz文件大小的...
1 2 3 4 5 ... 20
收藏数 515,163
精华内容 206,065
关键字:

文件上传与下载