天天看点

文件上传下载 Upload&Download

文件的上传下载 Upload&Download

(一)文件的上传

  • 文件的上传即将本地文件上传到远程服务器端
  • 文件上传的流也需要放到一个表单中

2、文件上传的表单的要求

  1. 文件上传的表单需要设置的请求方式是POST请求
  2. 文件上传的表单项的type属性需要指定为:file
    <input type="file" name="photo">
               
  3. 给form表单添加一个enctype属性
    该属性的默认值是:application/x-www-form-urlencoded
    当是该属性值时表单中的内容会使用URL进行编码
    我们上传文件需要将该属性的值修改为:multipart/form-data
    使用该值时表单中的表单项会以一个多部件的形式提交到服务器,
    一个表单项就是一个多部件,而且各个多部件之间使用像------WebKitFormBoundarypkeMFtY9i1D0COuu这样的分隔符进行分割
               

3 Upload装备三个核心类 七个核心方法

FileUpload是Apache为我们提供的专门用来进行文件上传和下载的工具类

使用FileUpload需要导入以下jar包

    commons-fileupload-1.3.1.jar
    commons-io-2.5.jar

核心类:

<1>DiskFileItemFactory
创建工厂类实例

<2>ServletFileUpload
创建解析器类实例

<3>FileItem
通过解析器解析请求之后得到的没个多部件就对应一个个FileItem对象

核心方法:

isFormField()
用来判断表单项是否是一个普通表单项
getFieldName()
用来获取表单项中的name属性值
getString(String encoding)
用来获取表单项中输入的value属性值,方法中传入一个字符集
getContentType()
用来获取文件的类型,是一个MIME值
getName()
用来获取文件名
getSize()
用来获取文件的大小,单位字节
write(File file)
将文件写到某个地方
           

具体实现:

jsp页面的实现如下:

<body>
<form action="${pageContext.request.contextPath}/uploadServlet" method="post" enctype="multipart/form-data">
  <center>
    <table height="250px">
         <tr>
            <td>用户名:</td>
            <td><input type="text" name="userName"/></td>
         </tr>
         <tr>
            <td>文件1:</td>
            <td><input type="file" name="file1"/></td>
         </tr>
         <tr>
            <td>文件2:</td>
            <td><input type="file" name="file2"/></td>
         </tr>
         <tr>
            <td>文件3:</td>
            <td><input type="file" name="file3"/></td>
         </tr>
         <tr>
            <td></td>
            <td><input type="submit" value="确定"/></td>
         </tr>
         <tr>
             <td>
             <a href="${pageContext.request.contextPath }/downLoadServlet" target="_blank" rel="external nofollow" >更多下载资源</a>
             </td>
         </tr>
          <tr>
            <td><span style="color: red">${requestScope.msg }</span></td>
          </tr>
          <tr>
            <td><span style="color: green">${requestScope.mesgsuccess }</span></td>
          </tr>
    </table>
    </center>
</form>
</body>
           

实现文件上传的Servlet如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*用此方式获取不到表单提交参数正确的实现如下
    String username = request.getParameter("username");
    String file1 = request.getParameter("file1");
    String file2 = request.getParameter("file2");
    String file3 = request.getParameter("file3");
    System.out.println(username+file1+file2+file3);*/

    //1.创建工厂类实例
    DiskFileItemFactory factory=new DiskFileItemFactory();
    //2.创建解析器类实例
    ServletFileUpload fileUpload=new ServletFileUpload(factory);
    //设置单个文件的大小不超过200KB
    fileUpload.setFileSizeMax(1024*400*10);
    //设置文件的总大小不超过450KB
    fileUpload.setSizeMax(1024*400*30);
    //3.解析请求
    try {
        List<FileItem> parseRequest = fileUpload.parseRequest(request);
        for (FileItem fileItem : parseRequest) {

            /*核心方法:
             * isFormField():用来判断表单项是否是一个普通表单项
             * getFieldName():用来获取表单项中的name属性值
             * getString(String encoding):用来获取表单项中输入的value属性值,方法中传入一个字符集
             * 
             * getContentType():用来获取文件的类型,是一个MIME值
             * getName():用来获取文件名
             * getSize():用来获取文件的大小
             * write(File file):将文件写到硬盘上
             */

            if(fileItem.isFormField()) {
                //证明是一个普通表单项
                //获取name属性值
                String fieldName = fileItem.getFieldName();
                //获取用户输入的值设置乱码
                String inputValue = fileItem.getString("UTF-8");

                System.out.println("表单项的name属性值为:"+fieldName);
                System.out.println("表单项中用户输入的值是 :"+inputValue);
            }else {
                //证明提交类型为文件 获取文件的类型
                String contentType = fileItem.getContentType();
                //获取文件名
                String name = fileItem.getName();
                //截取文件名 不要前面的路径(因为ie浏览器会带路径)
                if(name.contains("\\")) {
                    name=name.substring(name.lastIndexOf("\\")+1);
                }
                //获取单个文件的大小
                long fileSize = fileItem.getSize();

                System.out.println("文件的类型是:"+contentType);
                System.out.println("文件名是:"+name);
                System.out.println("文件的大小是:"+fileSize+"字节");

                //获取服务器端upload目录的真实路径(将文件上传到服务器)
                ServletContext servletContext = this.getServletContext();
                String realPath = servletContext.getRealPath("/upload");

                //创建目录
                File file=new File(realPath);
                if(!file.exists()){
                    //创建这个目录
                    file.mkdirs();
                }
                //使用UUID生成一个全球唯一的字符串
                String uuid = UUID.randomUUID().toString().replace("-","");
                //将上传的文件写到服务器端的upload目录中
               fileItem.write(new File(realPath+"/"+uuid+"_"+name));
            }

        }
    } catch (FileSizeLimitExceededException e) {
//e.printStackTrace();
        //设置一个错误消息
        request.setAttribute("msg", "单个文件不要超过4MB!");
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    } catch (SizeLimitExceededException e) {
//  e.printStackTrace();
        //设置一个错误消息
        request.setAttribute("msg", "总文件大小不要超过12MB!");
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    } catch (Exception e) {
        e.printStackTrace();
    }
    request.setAttribute("mesgsuccess", "上传文件成功!!");
    request.getRequestDispatcher("/index.jsp").forward(request, response);
   }
           

(二)文件的下载

文件的下载即将文件从服务器端下载到本地

文件的下载只需要将文件的地址作为一个超链接显示在浏览器端,然后点击超链接即可完成下载

但是这样做对于支持该文件格式的浏览器来说并不会下载该文件,而是直接将这个文件打开;

而且我们也不可以给文件设置下载的权限,所以我们通常将被下载的文件放到WEB-INF下,通过

Servlet来下载文件

1.通过在Servlet下载文件

1)创建一个输入流

2)设置两个响应头

3)使用输出流输出到浏览器端

2.具体实现:

Servlet实现如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取文件在服务器端的真实路径
            ServletContext servletContext = this.getServletContext();

            String realPath = servletContext.getRealPath("/WEB-INF/download/相见恨晚.mp3");

            //1.创建一个输入流
            InputStream is = new FileInputStream(realPath);


            String fileName = "相见恨晚.mp3";

            //获取用户使用的浏览器
            String header = request.getHeader("User-Agent");
            if(header.contains("Firefox")){
                //证明使用的是火狐浏览器
                //对应火狐浏览器,我们需要进行BASE64编码
                fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
            }else{
                //对文件名进行URL编码
                fileName = URLEncoder.encode(fileName, "UTF-8");
            }
            //2.设置两个响应头
            //①设置文件的类型,是一个MIME值
            //获取文件的MIME值
            String mimeType = servletContext.getMimeType(realPath);
            System.out.println(mimeType);

            response.setHeader("Content-Type", mimeType);
            //②设置浏览器怎样处理当前文件
            response.setHeader("Content-Disposition", "attachment; filename="+fileName);
            //3.使用输出流将文件输出到浏览器
            ServletOutputStream os = response.getOutputStream();
            //将输入流复制到输出流中
            IOUtils.copy(is, os);
            //关闭流
            is.close();
}
           

继续阅读