• 文件上传和下载


    一.文件的上传
    (一)基本概念及其入门案例
    1.什么是文件上传:将本地的文件上传到服务器端。
    2.应用:百度网盘,上传照片,上传附件。
    3.javaweb端实现文件上传;
    客户端:需要文件的输入项 <input type="file"/>
    必须有三点设置:
    1)type="file" name 必须有 name="myfile"
    2)form表单 method="post"提交方式 (get参数显示在url上,get数据大小1k)
    3)form表单 enctype="multipart/form-data" 编码格式
    服务端:写一段文件上传的程序。
    requestl.getInputStream(); 获取输入流
    System.out.write();

    4.fileupload 文件上传的组件
    1)jspsmartupload 上传组件,嵌入在jsp中。model1时代,jsp。
    2)jsp+servlet时代 fileuplaod

    5.fileupload的jar commons-fileupload-1.2.1jar包和commons-io-1.4jar包 要一起使用。 依赖。

    package cn.itcast.servlet;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.List;
    import java.util.UUID;
    
    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;
    
    import cn.itcast.util.UploadUtil;
    
    public class UploadServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            String filedesc = request.getParameter("filedesc");
            System.out.println("文件描述:"+filedesc);
            // 获取输入流
            //InputStream in = request.getInputStream();
            // 打印控制台上
            /*int b;
            while((b = in.read()) != -1){
                System.out.write(b);
            }
            System.out.flush();*/
            
            if(!ServletFileUpload.isMultipartContent(request)){
                throw new RuntimeException("请设置正确的enctype");
            }
            
            /**
             * 1.创建磁盘文件项工厂
             */
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 设置内存缓冲区的大小
            factory.setSizeThreshold(2*1024*1024);  //2M
            // 设置临时文件的存储位置
            String temppath = this.getServletContext().getRealPath("/temp");
            File filetemp = new File(temppath);
            factory.setRepository(filetemp);
            
            /**
             * 2.创建文件上传类
             */
            ServletFileUpload upload = new ServletFileUpload(factory);
            // 设置上传文件的总大小
            upload.setSizeMax(50L*1024*1024); // 50M
            // 设置文件名称的编码
            upload.setHeaderEncoding("UTF-8");
            
            /**
             * 3.解析request
             */
            try {
                List<FileItem> list = upload.parseRequest(request);
                /**
                 * 4.循环遍历list集合,拿到fileItem对象,判断是否普表单项
                 */
                for (FileItem fileItem : list) {
                    // isFormField()
                    if(fileItem.isFormField()){
                        // 普通表单项
                        // 获取参数的名称
                        String name = fileItem.getFieldName();
                        // 获取值
                        //String value = fileItem.getString();
                        String value = fileItem.getString("UTF-8");
                        System.out.println(name+" = "+value);
                    }else{
                        // 文件上传项
                        // 获取文件的名称
                        String filename = fileItem.getName();
                        // 先判断filename不能空
                        if(filename == null || filename.trim().length() == 0){
                            throw new RuntimeException("请选择文件");
                        }
                        // 解决IE6的问题  D:class
    esourcehello.txt
                        int index = filename.lastIndexOf("\");
                        if(index != -1){
                            filename = filename.substring(index+1);
                        }
                        //解决文件名重名的问题
                        filename = UUID.randomUUID().toString()+"_"+filename;
                        // 目录分离
                        String dir = UploadUtil.getRanromDir(filename);
                        
                        System.out.println("文件名称:"+filename);
                        // 获取输入流
                        InputStream in = new BufferedInputStream(fileItem.getInputStream());
                        // 先获取upload的绝对路径
                        String filepath = this.getServletContext().getRealPath("/upload"+dir);
                        // 创建多级目录
                        new File(filepath).mkdirs();
                        // 创建file对象
                        File file = new File(filepath,filename);
                        // 输出流
                        OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
                        int b;
                        while((b = in.read()) != -1){
                            os.write(b);
                        }
                        os.close();
                        in.close();
                        // 删除临时文件(必须写在流关闭之后)
                        fileItem.delete();
                    }
                }
                
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            System.out.println(System.getProperty("java.io.tmpdir"));
        }
    
    }


    (二)入门案例存在的问题
    1.IE6上传文件的问题:
    产生原因:把文件的绝对路径传过来了。
    解决办法:切割。把文件名称切出来。
    // 解决IE6的问题 D:class esourcehello.txt
    int index = filename.lastIndexOf("\");
    if(index != -1){
    filename = filename.substring(index+1);
    }
    2.注意事项(*****)
    String filedesc = request.getParameter("filedesc"); 在文件上传 enctype="multipart/form-data"拿不到值了。
    想拿到值就下面方法。
    // 获取参数的名称
    String name = fileItem.getFieldName();
    // 获取值
    String value = fileItem.getString();

    (三)文件上传的核心类及其API
    1.磁盘文件项工厂类 DiskFileItemFactory
    1)DiskFileItemFactory(int sizeThreshold, java.io.File repository) 第一个参数内存缓冲区的大小 第二个参数临时文件的存储位置
    内存缓冲区:上传文件时,文件首先会上传到内存缓冲区中,上传的文件的大小超过设置的内存缓冲区的大小,就会产生临时文件。
    临时存储位置:用来保存临时文件的。

    2)void setSizeThreshold(int sizeThreshold) 设置内存缓冲区的大小 默认10k
    3)void setRepository(java.io.File repository) 设置临时文件存储位置 System.getProperty("java.io.tmpdir") C:UsersADMINI~1AppDataLocalTemp

    2. 文件上传类 ServletFileUpload
    1)static boolean isMultipartContent(javax.servlet.http.HttpServletRequest request) 判断enctype是否是multipart方式
    2)java.util.List parseRequest(javax.servlet.http.HttpServletRequest request) 解析request 返回list<FileItem>集合
    3)void setSizeMax(long sizeMax) 设置上传所有文件的总大小 和 void setFileSizeMax(long fileSizeMax) 设置单个上传文件的大小
    4)(*****)void setHeaderEncoding(java.lang.String encoding) 设置编码 可以解决中文文件名乱码的问题
    5)void setProgressListener(ProgressListener pListener) 设置进度条的监听器 进度条速度 剩余时间 剩余大小

    3. 文件项FileItem
    1)boolean isFormField() 判断是否是普通表单项还是文件上传项
    if(fileItem.isFormFiele()){
    // 表单
    2)java.lang.String getFieldName() 获取参数的名称
    3)java.lang.String getString() 获取值
    4)(*****)java.lang.String getString(java.lang.String encoding) 设置表单中文的编码 解决普通表单项的中文乱码的问题
    }else{
    // 文件
    5)java.io.InputStream getInputStream() 获取输入流
    6)java.lang.String getName() 获取文件名称
    }
    7)void delete() 删除临时文件((必须写在流关闭之后))

    (四)多文件上传案例(js控制)
    需求:多文件上传。

    (五)上传文件的扩展
    1.上传文件存放目录问题:
    1)在webroot目录下,安全级别较低,允许用户直接访问。
    购物商城的网站:京东。

    2)上传文件目录访问WEB-INF目录下,安全级别较高。通过程序。
    例子:视频网站。

    2.文件名重名的问题
    解决办法:UUID+"_"+文件名称

    3.解决一个目录内文件过多的问题(目录分离算法)
    1)根据上传文件的时间(周,月)
    2)根据上传文件的数量(3000)
    3)根据用户创建一个文件夹(张三,李四)
    4)根据唯一文件名的hashcode值算法。


    二.文件的下载
    (一)基本概念及其入门案例
    1.什么的文件的下载:将服务器的文件下载到本地。
    2.应用:百度网盘,下载歌曲,下载图片。
    3.javaweb实现文件的下载:
    1)超链接下载 <a href="文件的绝对路径">文件名称</a>
    浏览器可以解析你文件的格式。浏览器直接打开。

    2)程序的文件下载。
    接收文件的名称,获取download的绝对路径,并且拼接file对象,读入到输入流中。
    两点注意:两个头一个流
    两个响应头:设置Content-Type 属性 MIME类型
    设置Content-Disposition 值attachment;filename= + 文件名称 以附件的形式打开。
    一个响应流:向浏览器输出 response.getOutputStream()

    (二)文件下载扩展案例
    需求:在磁盘随便指定一个目录,要把该目录下的所有文件及其子目录下的所有文件列在页面上,并且提供下载。
    采用广度非递归的遍历,依赖于数据结构。队列 FIFO 先进先出 JDK5.0 提供了接口 Queue

    package cn.itcast.servlet;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 下载的入门案例
     * @author Administrator
     *
     */
    public class DownloadServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 获取文件的名称
            String filename = request.getParameter("filename");
            // 获取download的绝对路径
            String filepath = this.getServletContext().getRealPath("/download");
            // 创建file对象
            File file = new File(filepath,filename);
            // 读入到输入流
            InputStream in = new BufferedInputStream(new FileInputStream(file));
            // 设置两个头
            String mimeType = this.getServletContext().getMimeType(filename);
            // 设置类型
            response.setContentType(mimeType);
            // 设置以附件形式打开
            response.setHeader("Content-Disposition", "attachment;filename="+filename);
            // 输出流
            OutputStream os = response.getOutputStream();
            int b;
            while((b = in.read()) != -1){
                os.write(b);
            }
            os.close();
            in.close();
        }
    
    }


    2.get方式提交 中文乱码
    filepath = new String(filepath.getBytes("ISO-8859-1"),"UTF-8");

    3.IE6中文乱码
    产生原因:代码没有问题。IE6对中文的编码有bug。
    解决办法:自己编码。URLEncoder.encode(f.getCanonicalPath(), "UTF-8")

    4.弹出的下载框显示的中文乱码


    三.JavaMail(邮件)
    (一)邮件的基本概念及其传输过程
    1.为什么学习邮件:比较好的用户体验,比较火的技术。
    2.常见邮件:祝福邮件,通知邮件,垃圾邮件

    3.基本概念
    1)邮件服务器:是一台电脑,装关于邮件服务器的软件。收发邮件。
    2)电子邮箱:邮件服务器上的账号,在邮件服务器分配一块空间,用来保存邮件。

    3)邮件的传输协议:
    发送邮件协议:SMTP协议 默认端口 25

    接收邮件协议:POP3协议 默认端口 110

    接收邮件协议:IMAP协议 默认端口 143
    区别:允许不用下载,直接在服务器端可以修改。
    gmail 支持IMAP

    4.邮件的传输过程
    看图七

    (二)通过telnet命令手动发送邮件(网络)
    1.如果是win7的系统,需要手动开启telnet命令。如果xp不用。
    2.发送邮件的协议(SMTP)
    1)telnet smtp.sina.com 25 链接新浪的发送邮件的服务器
    2)ehlo hi 打个招呼
    3)auth login 是否需要登陆认证
    4)输入用户名 (必须要经过BASE64进行编码)
    5)输入密码
    6)mail from:<javamail_day@sina.com> 发件人
    7)rcpt to:<javamail_day@163.com> 收件人
    8)Data RFC822文档(规范)
    9)输入邮件内容(RFC822文档)
    10). 代表邮件的结束
    11)quit 断开链接


    3.RFC822文档
    包含邮件头 和邮件体,中间用空行分隔。
    邮件头:
    from:<javamail_day@sina.com> 发件人
    to:<javamail_day@163.com> 收件人
    subject:girl 邮件的标题

    邮件体:
    I LOVE YOU TOO TOO

    4.接收邮件的协议 POP3协议
    telnet pop3.163.com 110 链接接收邮件服务器
    user 输入用户名
    pass 输入密码
    stat 返回邮件的数量
    list 返回邮件列表结合
    retr 2 访问第二封邮件
    quit 端口链接

    (三)邮件服务器,客户端安装及其telnet命令发送邮件(本机)
    1.安装邮件服务器
    配置:工具--服务器设置--修改域名(estore.com)
    新建账号:账号--新建账号。

    2.安装客户端软件
    安装foxmail。
    配置:建立新的账户:bbb@estore.com 密码111
    指定邮件服务器:localhost


    (四)通过JavaMail创建简单的邮件
    1.javamial sun官方提供api,关于邮件的api。
    2.下载jar包 javamail1_4_4和jaf-1_1_1 包,必须一起使用,依赖。
    JDK6.0之后 jaf内置。如果是JDK1.6版本之前,需要引入jaf的包。

    3.入门案例。
    1)Session 链接服务器会话。
    2)Message 邮件对象
    3)Transport 发送邮件工具类

    4.邮件的内容打印在控制台上保存
    java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
    产生的原因:myeclipse自带的jar与javamail的jar包冲突导致。
    解决办法:

  • 相关阅读:
    Number Sequence
    不容易系列之(3)—— LELE的RPG难题
    又见回文
    统计元音
    数列
    regular expression
    野兽男孩
    GameStd
    boost and qt compile.
    kde4 + compiz只有两个桌面的问题
  • 原文地址:https://www.cnblogs.com/appium/p/10276427.html
Copyright © 2020-2023  润新知