文件上传和下载

文件上传/下载

上传:

表单method="post" entype="multipart/from-data"

表单中需要提交文件表单项 必须要有name属性

 

Servlet

当enctype="multipart/from-data" 使用 getparmeter方法就不能用了

适用 servletInputStream request.getInputStream();包含整个请求体。

 

 

上传的细节问题:

文件必须保存在web-inf下!

    目的是不让浏览器直接访问到

文件名相关的问题

    有的浏览器上传的文件名是绝对路径,这需要切割!c:\files\baibing.jpg

String filename=fi2.getname();

Int index=filename.lastIndexOf("\\");

If(index!=-1){

    Filename=filename.substring(index+1);

}

    文件名乱码或者普通表单项乱码

Request.setCharsetEncoding("utf-8");

servletFileUpload.setHeaderEncoding("utf-8");

    文件同名问题 我们需要为每个文件设置一个uuid

Filename=commonUtils.uuid()+"_"+filename;

目录打散

    不能在一个目录下存放之多个文件

上传文件的大小限制

    单个文件大小限制

Sfu.setFileSizeMax(100*1024)//限制文件大小为100k

//必须要在获取解析之前执行

Sfu.setsizemax(1024*1024);//超出是抛出异常

    整个请求所有数据大小限制

缓存大小与临时目录

 

package com.pcx.servlet;

 

import java.io.File;

import java.io.IOException;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.FileUploadException;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

 

public class Upload2Servlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        response.setContentType("text/html;charset=utf-8");

        DiskFileItemFactory factory=new DiskFileItemFactory();

        ServletFileUpload sfu=new ServletFileUpload(factory);

        

        try {

            List<FileItem>fileItemlist=sfu.parseRequest(request);

            FileItem fi1=fileItemlist.get(0);

            FileItem fi2=fileItemlist.get(1);

            System.out.println("普通表单项演示"+fi1.getFieldName()+"=="+fi1.getString("UTF-8"));

            System.out.println("文件表单项获取:");

            System.out.println("Content-type:"+fi2.getContentType());

            System.out.println("size"+fi2.getSize());

            System.out.println("filename"+fi2.getName());

            

            File desc=new File("D:/linghucong.jpg");//一般保存在web-Inf

            fi2.write(desc);

        } catch (FileUploadException e) {

            e.printStackTrace();

        } catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

 

 

 

</head>

 

<body>

This is my JSP page. <br>

<form action="<c:url value='/Upload2Servlet'/>" method="post" enctype="multipart/form-data">

用户名<input type="text" name="username">

照片<input type="file" name="zhaopian">

<input type="submit" value="提交"/>

</form>

</body>

</html>

 

public class Upload3Servlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        response.setContentType("text/html;charset=utf-8");

        //工厂

        DiskFileItemFactory factory=new DiskFileItemFactory();

        //解析器

        ServletFileUpload sfu=new ServletFileUpload(factory);

        try {

            List<FileItem>list=sfu.parseRequest(request);

            FileItem fi1=list.get(1);

            

            //拿到文件的根路径

            String root=this.getServletContext().getRealPath("/WEB-INF/files/");

            //得到文件名 处理绝对路径问题 得到hashCode 转为16进制 使用前两个字符生成目录

            

            String filename=fi1.getName();

            int index=filename.indexOf("\\");

            if(index!=-1){

                filename=filename.substring(index+1);

            }

            

            //添加文件的前缀问题

            String savename=CommonUtils.uuid()+"_"+filename;

            

            //得到hashcode

            int hcode=filename.hashCode();

            String hex=Integer.toHexString(hcode);

            

            //生成对应的两层结构

            File dirFile=new File(root,hex.charAt(0)+"/"+hex.charAt(1));

            //创建目录连

            dirFile.mkdirs();

            

            //创建目标文件

            File dest=new File(dirFile,savename);

            

            //保存

            fi1.write(dest);

        } catch (FileUploadException e) {

            e.printStackTrace();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

 

}

 

 

 

    fi1.write(dest);

        } catch (FileUploadException e) {

            if( e instanceof FileUploadBase.FileSizeLimitExceededException){

                request.setAttribute("msg","你上传的文件超过100k");

                request.getRequestDispatcher("/form3.jsp").forward(request, response);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

 

 

<span>${requestScope.msg }</span>

下载

向客户端响应字节数据。

Response.getoutputStream

两个头 一个流

Content-type mime类型

Content-disposition 默认inline

文件名乱码 问题

Firefox 使用的是base64编码

大部分的浏览器是url编码

通用方案:filename=new String (filename.getByte("GBK"),"iso-8859-1")

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        String filename="D:/令狐冲.jpg";

        String framename=new String(filename.getBytes("GBK"),"ISO-8859-1");

        

        String contenttype=this.getServletContext().getMimeType(filename);

        String contentDisposition="attchment;filename="+framename;

        FileInputStream in=new FileInputStream(filename);

        response.setHeader("Content-Type", contenttype);

        response.setHeader("Content-Disposition", contentDisposition);

        

        ServletOutputStream out=response.getOutputStream();

        

        IOUtils.copy(in, out);

        in.close();

    }

posted @ 2015-12-05 14:19  coder程  阅读(400)  评论(0编辑  收藏  举报