JAVA EE-文件上传

来源:互联网 发布:安卓开发java基础 编辑:程序博客网 时间:2024/05/17 15:03

JAVA EE-文件上传

应该相信,自己是生活的战胜者。 —— 雨果

文件下载

首先我们复习一下文件下载的内容

静态下载
public class AServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {            //1 准备工作                //设置content-type            response.setContentType(getServletContext().getMimeType("xxx.zip"));                //添加响应头 content-disposition            response.setHeader("Content-Disposition", "attachment;filename=apache-tomcat-6.0.35.zip");              //2 获得输入流            InputStream is              = getServletContext().getResourceAsStream("/WEB-INF/apache-tomcat-6.0.35.zip");            //3 获得输出流            OutputStream os = response.getOutputStream();            //4 两个流对接            IOUtils.copy(is, os);    }}
根据用户的选择来获取下载

JSP文件:

 <body>    <a href="/day12-download/AServlet" >点击下载</a><br>    <a href="/day12-download/BServlet?name=apache-tomcat-6.0.35.zip" >apache-tomcat-6.0.35.zip</a><br>    <a href="/day12-download/BServlet?name=激活软件_v10.0.0.exe" >激活软件_v10.0.0.exe</a><br>  </body>

业务处理的Servlet

public class BServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //1 获得参数,拿到用户需要下载的文件名称        String fileName = request.getParameter("name");        fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8");        //2 准备工作        //设置content-type        response.setContentType(getServletContext().getMimeType(fileName));            //添加响应头 content-disposition        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));         //2 获得输入流        InputStream is          = getServletContext().getResourceAsStream("/WEB-INF/"+fileName);        //3 获得输出流        OutputStream os = response.getOutputStream();        //4 两个流对接        IOUtils.copy(is, os);        //关闭输出流        is.close();        os.close();    }}

下载的乱码问题

客户端的超连接中如果包含了中文,会出现get请求方式乱码问题

            <a href="${pageContext.request.contextPath}/download?filename=天空.mp3">下载王非天空.mp3</a>                    String filename = request.getParameter("name"); // yog.rar / 她说.mp3                    byte[] b = filename.getBytes("ISO-8859-1");                    filename = new String(b,"UTF-8");                    实际上Get提交时包含中文乱码的解决。

如果下载文件名称中出现了中文乱码问题

            <a href="${pageContext.request.contextPath}/download?filename=天空.mp3">下载王非天空.mp3</a>                    String filename = request.getParameter("name"); // yog.rar / 她说.mp3                    byte[] b = filename.getBytes("ISO-8859-1");                    filename = new String(b,"UTF-8");                    实际上Get提交时包含中文乱码的解决。

文件上传

  • 为什么使用文件上传?

    • 例如社交网站需要提供用户照片.
    • 很多企业内部,商品网站维护时需要上传一些文件
    • 邮箱需要上传附件….
  • 文件上传的操作

    • 请求方式必须是post
    • 需要使用组件
    • 表单必须设置encType=”multipart/form-data”
    • 上传文件的input 中,name属性必须要填写,不然不会上传.

这样一来,通过request对象,获取InputStream,可以将浏览器提交的所有请求正文读取到.

文件上传需要的插件

    commons-fileupload 它是常用的一个文件上传工具    使用时要导入两个jar包        commons-fileupload-1.2.1.jar        commons-io-1.4.jar

一个上传的浏览器端代码

  <body>    <!--     1.文件上传,表单必须是post提交    2.文件上传,还需要在表单上加上enctype属性(提交请求正文的类型)            *application/x-www-form-urlencoded(默认取值,普通提交)            *multipart/form-data(多段式提交)    3.  文件上传,使用<input type="file" name="photo" /> 标签,并且必须有name属性     -->    <form action="/day12-upload/BServlet"  method="post" encType="multipart/form-data"  >         用户名:<input type="text" name="name" /><br>        个人近照:<input type="file" name="photo" /><br>        <input type="submit" value="上传"  />    </form>  </body>

下面演示如何使用第三方的jar包来优化文件上传处理

public class BServlet extends HttpServlet {    //使用文件上传工具类(第三方)    // 导包  => commons-fileupload-1.2.1.jar    //     => commons-io-1.4.jar    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 1 创建配置工厂        DiskFileItemFactory factory = new DiskFileItemFactory();        //2 根据配置工厂创建解析请求中文件上传内容的解析器        ServletFileUpload upload = new ServletFileUpload(factory);        //3 判断当前请求是否是多段式提交        if(!upload.isMultipartContent(request)){            //普通表单提交            throw new RuntimeException("不是多段式提交!");        }        try {        //4 解析request对象            List<FileItem>  list = upload.parseRequest(request);            if(list!=null){                for(FileItem item : list){                    //判断当前上传段是普通字段,还是文件上传                    if(!item.isFormField()){//文件上传段                        String fName = item.getFieldName();                        InputStream is = item.getInputStream();//获得文件上传段中,文件的流                        FileOutputStream fos = new FileOutputStream("d://upload/xxx.jpg");                        IOUtils.copy(is, fos);                        fos.close();                    }else{//普通字段段                        String name = item.getFieldName();                        String value = item.getString();                        System.out.println(name+"==>"+value);                    }                }            }        } catch (FileUploadException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

文件上传段与普通表单段的区别如下
这里写图片描述

fileupload工具类详解

public class CServlet extends HttpServlet {    //fileupload 工具类使用详解    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {    //1 创建配置工厂=> 有参的构造可以 直接设置下面两个配置        DiskFileItemFactory factory  = new DiskFileItemFactory();    //1.1 设置文件上传临时目录 => 默认位置 => tomcat/temp        factory.setRepository(new File("d:/temp"));    //1.2 设置文件写入硬盘的缓冲区大小=>默认值=>10k        factory.setSizeThreshold(10240);    //2 根据配置工厂创建解析器(解析request对象)        ServletFileUpload upload = new ServletFileUpload(factory);    //2.1 判断当前请求是否是多段式提交        upload.isMultipartContent(request);    //2.2 设置多段中每段 段头 在解析时,使用什么码表解码 => 当段头中出现中文时,一定要调用该方式指定段头码表        upload.setHeaderEncoding("UTF-8");    //2.3 设置文件最大上传大小 (单位:字节)        upload.setSizeMax(1024*1024*10); //单次请求,总上传大小限制  10兆        upload.setFileSizeMax(1024*1024);// 每个文件上传段,大小限制 1兆        List<FileItem> list = null;        try {            //2.4 解析request,将每个分段中的内容封装到FileItem中            list = upload.parseRequest(request);        } catch (FileUploadException e) {            e.printStackTrace();        }        if(list!=null){            for(FileItem item : list){            //3.1 item 判断当前分段是否是普通表单段                    boolean flag = item.isFormField();                    //普通段                    //3.2获得 表单提交的键.(input元素,name属性的值)                    String fname = item.getFieldName();                    //3.3 返回文件名称                    String  name = item.getName();                    //3.4 获得文件上传中的正文                    //item.getInputStream();                    //3.5 以字符串形式返回段体中的内容 注意:文件上传段不建议使用该方法.                     String content= item.getString();                    //3.6  删除上传的临时文件                    item.delete();                    System.out.println("是否是普通表单提交:"+flag+",表单提交的键:"+fname+",文件名称:"+name+",文件内容:"+content);            }        }    }}

关于乱码问题的研究
当上传的文件名中有中文时,如果码表不当就会造成乱码问题的产生。

public class DServlet extends HttpServlet {    //上传文件名称是中文,乱码问题    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 1 创建配置工厂                DiskFileItemFactory factory = new DiskFileItemFactory();        //2 根据配置工厂创建解析请求中文件上传内容的解析器                ServletFileUpload upload = new ServletFileUpload(factory);            //解决文件名称中文乱码                upload.setHeaderEncoding("UTF-8");                //3 判断当前请求是否是多段式提交                if(!upload.isMultipartContent(request)){                    //普通表单提交                    throw new RuntimeException("不是多段式提交!");                }                try {                //4 解析request对象                    List<FileItem>  list = upload.parseRequest(request);                    if(list!=null){                        for(FileItem item : list){                            //判断当前上传段是普通字段,还是文件上传                            if(!item.isFormField()){//文件上传段                                String fileName = item.getName();                                System.out.println(fileName);                            }                        }                    }                } catch (FileUploadException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }    }}

设置上传文件的最大大小

public class FServlet extends HttpServlet {    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 1 创建配置工厂        DiskFileItemFactory factory = new DiskFileItemFactory();//2 根据配置工厂创建解析请求中文件上传内容的解析器        ServletFileUpload upload = new ServletFileUpload(factory);        //设置文件上传大小限制        upload.setFileSizeMax(1024);        try {            upload.parseRequest(request);        } catch (FileUploadException e) {            e.printStackTrace();            throw new RuntimeException("文件大小不能超过1kb!");        }}}
        可以设置上传文件大小,如果超过设置大小.将会抛出异常(默认没有最大值)            void setFileSizeMax(long fileSizeMax) 设置单个文件上传大小             void  setSizeMax(long sizeMax) 设置总文件上传大小 

如何实现保存的文件名不会重复

public class GServlet extends HttpServlet {    //如果将文件全部保存 => 保证文件名称不能重复    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 1 创建配置工厂        DiskFileItemFactory factory = new DiskFileItemFactory();        //2 根据配置工厂创建解析请求中文件上传内容的解析器        ServletFileUpload upload = new ServletFileUpload(factory);        //3 判断当前请求是否是多段式提交        if(!upload.isMultipartContent(request)){            //普通表单提交            throw new RuntimeException("不是多段式提交!");        }        try {        //4 解析request对象            List<FileItem>  list = upload.parseRequest(request);            if(list!=null){                for(FileItem item : list){                    //判断当前上传段是普通字段,还是文件上传                    if(!item.isFormField()){//文件上传段                        String fName = item.getFieldName();                        InputStream is = item.getInputStream();//获得文件上传段中,文件的流                        //保存之前,生成文件名称( 保证永远不重复)                        //生成随机字符串即可                        String fileName = UUID.randomUUID().toString();                        FileOutputStream fos = new FileOutputStream("d:/upload/"+fileName);                        IOUtils.copy(is, fos);                        fos.close();                    }                }            }        } catch (FileUploadException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

如何防止同一个目录之下上传文件数量过多?

public class HServlet extends HttpServlet {    //如何将上传文件分目录保存    // 使用登录用户的用户名 来创建不同的文件夹. 每个用户上传的文件就放到自己的文件夹中    // 按照日期分目录=> d:/upload/2015/08/24/    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 1 创建配置工厂        DiskFileItemFactory factory = new DiskFileItemFactory();        //2 根据配置工厂创建解析请求中文件上传内容的解析器        ServletFileUpload upload = new ServletFileUpload(factory);        //3 判断当前请求是否是多段式提交        if(!upload.isMultipartContent(request)){            //普通表单提交            throw new RuntimeException("不是多段式提交!");        }        try {        //4 解析request对象            List<FileItem>  list = upload.parseRequest(request);            if(list!=null){                for(FileItem item : list){                    //判断当前上传段是普通字段,还是文件上传                    if(!item.isFormField()){//文件上传段                        String fName = item.getFieldName();                        InputStream is = item.getInputStream();//获得文件上传段中,文件的流                        // 生成日期目录                        //1 获得当前日期=>目录结构 的 路径                        SimpleDateFormat format = new SimpleDateFormat("/yyyy/MM/dd/");                        String datepath = format.format( new Date()); //    /2015/08/24/                        //拼接完整保存目录路径                        String wholePath = "d:/upload"+datepath;// d:/upload/2015/08/24/                        //确保文件夹存在                        File directory = new File(wholePath);                        if(!directory.exists()){//如果文件夹结构不存在                            directory.mkdirs(); //创建文件夹结构                        }                        //保存之前,生成文件名称( 保证永远不重复)                        //生成随机字符串即可                        String fileName = UUID.randomUUID().toString();                        FileOutputStream fos = new FileOutputStream(wholePath+fileName);                        IOUtils.copy(is, fos);                        fos.close();                    }                }            }        } catch (FileUploadException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
0 0
原创粉丝点击