zoukankan      html  css  js  c++  java
  • 19、文件上传与下载/JavaMail邮件开发

    回顾:

    一、 监听器

    1. 生命周期监听器

    ServletRequestListener

    HttpSessionListener

    ServletContextListener

    1. 属性监听器

    ServletRequestAttributeListener

    HttpSessionAttributeListener

    ServletContextAttributeListener

    1. Session相关监听器
    2. 案例: 显示在线用户!

    监听器:ServletContextListener/HttpSessionListener

    二、 国际化

    1. 国际化资源文件: 基础名_语言_国家.properties   【通用】

    基础名.properties   (默认)

    1. 获取国际化文本

    a)       ResourceBundle工具类

    1. JSP页面国际化

    a)       Jstl提供的“国际化与格式化标签库” 

    1. 文件上传与下载

    1.1 文件上传

    案例:

               注册表单/保存商品等相关模块!

               --à 注册选择头像 / 商品图片

               (数据库:存储图片路径 / 图片保存到服务器中指定的目录)

    文件上传,要点:

    前台:

               1. 提交方式:post

               2. 表单中有文件上传的表单项: <input type=”file” />

               3. 指定表单类型:

                         默认类型:enctype="application/x-www-form-urlencoded"

                         文件上传类型:multipart/form-data

    手动实现文件上传

    <body> 

          <form name="frm_test" action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data">

              用户名:<input type="text" name="userName">  <br/>

             文件:   <input type="file" name="file_img">   <br/>

            

             <input type="submit" value="注册">

          </form>

      </body>

    public class UploadServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                 throws ServletException, IOException {

            /*

            request.getParameter(""); // GET/POST

            request.getQueryString(); // 获取GET提交的数据

            request.getInputStream(); // 获取post提交的数据   */

           

            /***********手动获取文件上传表单数据************/

           

            //1. 获取表单数据流

            InputStream in =  request.getInputStream();

            //2. 转换流

            InputStreamReader inStream = new InputStreamReader(in, "UTF-8");

            //3. 缓冲流

            BufferedReader reader = new BufferedReader(inStream);

            // 输出数据

            String str = null;

            while ((str = reader.readLine()) != null) {

                 System.out.println(str);

            }

           

            // 关闭

            reader.close();

            inStream.close();

            in.close();

        }

    输出结果:

    ------WebKitFormBoundaryGoQviatB7iM1dhPr

    Content-Disposition: form-data; name="userName"       【FileItem】

     

    Jack

    ------WebKitFormBoundaryGoQviatB7iM1dhPr

    Content-Disposition: form-data; name="file_img"; filename="reamde.txt"

    Content-Type: text/plain                                     【FileItem】

     

     

    test!!!!!!!!!!!!!

    test!!!!!!!!!!!!!

    ------WebKitFormBoundaryGoQviatB7iM1dhPr--

    总结:

    最终获取数据,要对上面的结果进行解析!

    文件上传,在开发中经常用,每次都写解析程序!(工具类)

    也可以使用开源的文件上传组件-FileUpload组件!

     

    Apache提供的文件上传组件:FileUpload组件

    文件上传功能开发中比较常用,apache也提供了文件上传组件!

    FileUpload组件:

               1. 下载源码

               2. 项目中引入jar文件

                                    commons-fileupload-1.2.1.jar  【文件上传组件核心jar包】

                                    commons-io-1.4.jar     【封装了对文件处理的相关工具类】

     

    public class UploadServlet extends HttpServlet {

     

        // upload目录,保存上传的资源

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                 throws ServletException, IOException {

           

            /*********文件上传组件: 处理文件上传************/

           

           

            try {

                 // 1. 文件上传工厂

                 FileItemFactory factory = new DiskFileItemFactory();

                 // 2. 创建文件上传核心工具类

                 ServletFileUpload upload = new ServletFileUpload(factory);

           

                 // 一、设置单个文件允许的最大的大小: 30M

                 upload.setFileSizeMax(30*1024*1024);

                 // 二、设置文件上传表单允许的总大小: 80M

                 upload.setSizeMax(80*1024*1024);

                 // 三、 设置上传表单文件名的编码

                 // 相当于:request.setCharacterEncoding("UTF-8");

                 upload.setHeaderEncoding("UTF-8");

                

                

                 // 3. 判断: 当前表单是否为文件上传表单

                 if (upload.isMultipartContent(request)){

                     // 4. 把请求数据转换为一个个FileItem对象,再用集合封装

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

                     // 遍历: 得到每一个上传的数据

                     for (FileItem item: list){

                         // 判断:普通文本数据

                         if (item.isFormField()){

                             // 普通文本数据

                             String fieldName = item.getFieldName();   // 表单元素名称

                             String content = item.getString();        // 表单元素名称, 对应的数据

                             //item.getString("UTF-8");  指定编码

                             System.out.println(fieldName + " " + content);

                         }

                         // 上传文件(文件流) ----> 上传到upload目录下

                         else {

                             // 普通文本数据

                             String fieldName = item.getFieldName();   // 表单元素名称

                             String name = item.getName();         // 文件名                

                             String content = item.getString();        // 表单元素名称, 对应的数据

                             String type = item.getContentType();  // 文件类型

                             InputStream in = item.getInputStream(); // 上传文件流

                            

                             /*

                              *  四、文件名重名

                              *  对于不同用户readme.txt文件,不希望覆盖!

                              *  后台处理: 给用户添加一个唯一标记!

                              */

                             // a. 随机生成一个唯一标记

                             String id = UUID.randomUUID().toString();

                             // b. 与文件名拼接

                             name = id +"#"+ name;

                            

                             // 获取上传基路径

                             String path = getServletContext().getRealPath("/upload");

                             // 创建目标文件

                             File file = new File(path,name);

                            

                             // 工具类,文件上传

                             item.write(file);

                             item.delete();   //删除系统产生的临时文件

                            

                             System.out.println();

                         }

                        

                     }

                    

                 }

                 else {

                     System.out.println("当前表单不是文件上传表单,处理失败!");

                 }

            } catch (Exception e) {

                e.printStackTrace();

            }

           

           

    }

    文件上传与下载,完整案例:

    步骤:

    1. 文件上传

    2. 列表下载

    Index.jsp

    <body> 

             <a href="${pageContext.request.contextPath }/upload.jsp">文件上传</a> &nbsp;&nbsp;&nbsp;

             <a href="${pageContext.request.contextPath }/fileServlet?method=downList">文件下载</a>

            

      </body>

    Upload.jsp

    <body> 

          <form name="frm_test" action="${pageContext.request.contextPath }/fileServlet?method=upload" method="post" enctype="multipart/form-data">

              <%--<input type="hidden" name="method" value="upload">--%>

              

              用户名:<input type="text" name="userName">  <br/>

             文件:   <input type="file" name="file_img">   <br/>

            

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

          </form>

      </body>

    Downlist.jsp

    <body> 

        <table border="1" align="center">

            <tr>

                 <th>序号</th>

                 <th>文件名</th>

                 <th>操作</th>

            </tr>

            <c:forEach var="en" items="${requestScope.fileNames}" varStatus="vs">

                 <tr>

                     <td>${vs.count }</td>

                     <td>${en.value }</td>

                     <td>

                         <%--<a href="${pageContext.request.contextPath }/fileServlet?method=down&..">下载</a>--%>

                         <!-- 构建一个地址  -->

                         <c:url var="url" value="fileServlet">

                             <c:param name="method" value="down"></c:param>

                             <c:param name="fileName" value="${en.key}"></c:param>

                         </c:url>

                         <!-- 使用上面地址 -->

                         <a href="${url }">下载</a>

                     </td>

                 </tr>

            </c:forEach>

        </table>        

      </body>

    FileServlet.java

     

    /**

     * 处理文件上传与下载

     * @author Jie.Yuan

     *

     */

    public class FileServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                 throws ServletException, IOException {

     

            // 获取请求参数: 区分不同的操作类型

            String method = request.getParameter("method");

            if ("upload".equals(method)) {

                 // 上传

                 upload(request,response);

            }

           

            else if ("downList".equals(method)) {

                 // 进入下载列表

                 downList(request,response);

            }

           

            else if ("down".equals(method)) {

                 // 下载

                 down(request,response);

            }

        }

       

       

        /**

         * 1. 上传

         */

        private void upload(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

           

            try {

                 // 1. 创建工厂对象

                 FileItemFactory factory = new DiskFileItemFactory();

                 // 2. 文件上传核心工具类

                 ServletFileUpload upload = new ServletFileUpload(factory);

                 // 设置大小限制参数

                 upload.setFileSizeMax(10*1024*1024);  // 单个文件大小限制

                 upload.setSizeMax(50*1024*1024);      // 总文件大小限制

                 upload.setHeaderEncoding("UTF-8");        // 对中文文件编码处理

     

                 // 判断

                 if (upload.isMultipartContent(request)) {

                     // 3. 把请求数据转换为list集合

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

                     // 遍历

                     for (FileItem item : list){

                         // 判断:普通文本数据

                         if (item.isFormField()){

                             // 获取名称

                             String name = item.getFieldName();

                             // 获取值

                             String value = item.getString();

                             System.out.println(value);

                         }

                         // 文件表单项

                         else {

                             /******** 文件上传 ***********/

                             // a. 获取文件名称

                             String name = item.getName();

                             // ----处理上传文件名重名问题----

                             // a1. 先得到唯一标记

                             String id = UUID.randomUUID().toString();

                             // a2. 拼接文件名

                             name = id + "#" + name;                      

                            

                             // b. 得到上传目录

                             String basePath = getServletContext().getRealPath("/upload");

                             // c. 创建要上传的文件对象

                             File file = new File(basePath,name);

                             // d. 上传

                             item.write(file);

                             item.delete();  // 删除组件运行时产生的临时文件

                         }

                     }

                 }

            } catch (Exception e) {

                 e.printStackTrace();

            }

                

           

        }

     

       

        /**

         * 2. 进入下载列表

         */

        private void downList(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

           

            // 实现思路:先获取upload目录下所有文件的文件名,再保存;跳转到down.jsp列表展示

           

            //1. 初始化map集合Map<包含唯一标记的文件名, 简短文件名>  ;

            Map<String,String> fileNames = new HashMap<String,String>();

           

            //2. 获取上传目录,及其下所有的文件的文件名

            String bathPath = getServletContext().getRealPath("/upload");

            // 目录

            File file = new File(bathPath);

            // 目录下,所有文件名

            String list[] = file.list();

            // 遍历,封装

            if (list != null && list.length > 0){

                 for (int i=0; i<list.length; i++){

                     // 全名

                     String fileName = list[i];

                     // 短名

                     String shortName = fileName.substring(fileName.lastIndexOf("#")+1);

                     // 封装

                     fileNames.put(fileName, shortName);

                 }

            }

           

            // 3. 保存到request域

            request.setAttribute("fileNames", fileNames);

            // 4. 转发

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

     

        }

     

       

        /**

         *  3. 处理下载

         */

        private void down(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

           

            // 获取用户下载的文件名称(url地址后追加数据,get)

            String fileName = request.getParameter("fileName");

            fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");

           

            // 先获取上传目录路径

            String basePath = getServletContext().getRealPath("/upload");

            // 获取一个文件流

            InputStream in = new FileInputStream(new File(basePath,fileName));

           

            // 如果文件名是中文,需要进行url编码

            fileName = URLEncoder.encode(fileName, "UTF-8");

            // 设置下载的响应头

            response.setHeader("content-disposition", "attachment;fileName=" + fileName);

           

            // 获取response字节流

            OutputStream out = response.getOutputStream();

            byte[] b = new byte[1024];

            int len = -1;

            while ((len = in.read(b)) != -1){

                 out.write(b, 0, len);

            }

            // 关闭

            out.close();

            in.close();

           

           

        }

       

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                 throws ServletException, IOException {

            this.doGet(request, response);

        }

     

    }

    2. JavaMail邮件开发

    (api  + 配置)

    开发中,邮件的应用?

               -à 注册,填写生日;  后期系统会自动发送生日祝贺

    -à 发货,发货提醒!邮件提醒!

    邮件:

               1. 发邮件;【程序中如何发邮件!】

               2. 收邮件;【很多客户端工具, foxmail 】

    邮件开发准备:

    准备工作, 环境搭建:

    1. 本地搭建一个邮件服务器

      -à 易邮服务器,eyoumailserversetup.exe

    2. 新建邮箱账号

      张三给李四发邮件。

      步骤1:

               新建域名: 工具, 服务器设置, 单域名框中输入 itcast.com

      步骤2:

               新建邮箱账号:  zhangsan@itcast.com

                      lisi@itcast.com

    3. 安装foxmail

               配置邮件发送服务器(smtp):  localhost      25

            邮件接收服务器(pop3):  localhost     110

               再新建账号,就可以接收邮件了!

    邮件开发之普通邮件:

    JavaMail开发,先引入jar文件:

               activation.jar   【如果使用jdk1.6或以上版本,可以不用这个jar文件】

               mail.jar       【邮件发送核心包】

     

    /**

     * 1. 发送一封普通邮件

     * @author Jie.Yuan

     *

     */

    public class App_SendMail {

     

        @Test

        public void testSend() throws Exception {

           

            //0. 邮件参数

            Properties prop = new Properties();

            prop.put("mail.transport.protocol", "smtp");  // 指定协议

            prop.put("mail.smtp.host", "localhost");      // 主机   stmp.qq.com

            prop.put("mail.smtp.port", 25);                   // 端口

            prop.put("mail.smtp.auth", "true");               // 用户密码认证

            prop.put("mail.debug", "true");                   // 调试模式

           

            //1. 创建一个邮件的会话

            Session session = Session.getDefaultInstance(prop);

            //2. 创建邮件体对象 (整封邮件对象)

            MimeMessage message = new MimeMessage(session);

            //3. 设置邮件体参数:

            //3.1 标题

            message.setSubject("我的第一封邮件 ");

            //3.2 邮件发送时间

            message.setSentDate(new Date());

            //3.3 发件人

            message.setSender(new InternetAddress("zhangsan@itcast.com"));

            //3.4 接收人

            message.setRecipient(RecipientType.TO, new InternetAddress("lisi@itcast.com"));

            //3.5内容

            message.setText("你好,已经发送成功!  正文....");  // 简单纯文本邮件

            message.saveChanges();   // 保存邮件(可选)

           

            //4. 发送

            Transport trans = session.getTransport();

            trans.connect("zhangsan", "888");

            // 发送邮件

            trans.sendMessage(message, message.getAllRecipients());

            trans.close();

        }

    }

    邮件开发之带图片

     

    /**

     * 带图片资源的邮件

     * @author Jie.Yuan

     *

     */

    public class App_2SendWithImg {

      

       // 初始化参数

       private static Properties prop;

       // 发件人

       private static InternetAddress sendMan = null;

       static {

         prop = new Properties();

         prop.put("mail.transport.protocol", "smtp"); // 指定协议

         prop.put("mail.smtp.host", "localhost");     // 主机   stmp.qq.com

         prop.put("mail.smtp.port", 25);           // 端口

         prop.put("mail.smtp.auth", "true");          // 用户密码认证

         prop.put("mail.debug", "true");           // 调试模式

         try {

            sendMan = new InternetAddress("zhangsan@itcast.com");

         } catch (AddressException e) {

            throw new RuntimeException(e);

         }

       }

     

       @Test

       public void testSend() throws Exception {

         // 1. 创建邮件会话

         Session session = Session.getDefaultInstance(prop);

         // 2. 创建邮件对象

         MimeMessage message = new MimeMessage(session);

         // 3. 设置参数:标题、发件人、收件人、发送时间、内容

         message.setSubject("带图片邮件");

         message.setSender(sendMan);

         message.setRecipient(RecipientType.TO, new InternetAddress("lisi@itcast.com"));

         message.setSentDate(new Date());

        

         /***************设置邮件内容: 多功能用户邮件 (related)*******************/

         // 4.1 构建一个多功能邮件块

         MimeMultipart related = new MimeMultipart("related");

         // 4.2 构建多功能邮件块内容 = 左侧文本 + 右侧图片资源

         MimeBodyPart content = new MimeBodyPart();

         MimeBodyPart resource = new MimeBodyPart();

        

         // 设置具体内容: a.资源(图片)

         String filePath = App_2SendWithImg.class.getResource("8.jpg").getPath();

         DataSource ds = new FileDataSource(new File(filePath));

         DataHandler handler = new DataHandler(ds);

         resource.setDataHandler(handler);

         resource.setContentID("8.jpg");   // 设置资源名称,给外键引用

        

         // 设置具体内容: b.文本

         content.setContent("<img src='cid:8.jpg'/>  好哈哈!", "text/html;charset=UTF-8");

        

         related.addBodyPart(content);

         related.addBodyPart(resource);

        

         /*******4.3 把构建的复杂邮件快,添加到邮件中********/

         message.setContent(related);

        

        

         // 5. 发送

         Transport trans = session.getTransport();

         trans.connect("zhangsan", "888");

         trans.sendMessage(message, message.getAllRecipients());

         trans.close();

       }

    }

     

    邮件开发之带图片 + 附件

     

    /**

     * 3. 带图片资源以及附件的邮件

     * @author Jie.Yuan

     *

     */

    public class App_3ImgAndAtta {

      

       // 初始化参数

       private static Properties prop;

       // 发件人

       private static InternetAddress sendMan = null;

       static {

         prop = new Properties();

         prop.put("mail.transport.protocol", "smtp"); // 指定协议

         prop.put("mail.smtp.host", "localhost");     // 主机   stmp.qq.com

         prop.put("mail.smtp.port", 25);           // 端口

         prop.put("mail.smtp.auth", "true");          // 用户密码认证

         prop.put("mail.debug", "true");           // 调试模式

         try {

            sendMan = new InternetAddress("zhangsan@itcast.com");

         } catch (AddressException e) {

            throw new RuntimeException(e);

         }

       }

     

       @Test

       public void testSend() throws Exception {

         // 1. 创建邮件会话

         Session session = Session.getDefaultInstance(prop);

         // 2. 创建邮件对象

         MimeMessage message = new MimeMessage(session);

         // 3. 设置参数:标题、发件人、收件人、发送时间、内容

         message.setSubject("带图片邮件");

         message.setSender(sendMan);

         message.setRecipient(RecipientType.TO, new InternetAddress("lisi@itcast.com"));

         message.setSentDate(new Date());

        

         /*

          * 带附件(图片)邮件开发

          */

         // 构建一个总的邮件块

         MimeMultipart mixed = new MimeMultipart("mixed");

         // ---> 总邮件快,设置到邮件对象中

         message.setContent(mixed);

         // 左侧: (文本+图片资源)

         MimeBodyPart left = new MimeBodyPart();

         // 右侧: 附件

         MimeBodyPart right = new MimeBodyPart();

         // 设置到总邮件块

         mixed.addBodyPart(left);

         mixed.addBodyPart(right);

        

         /******附件********/

         String attr_path = this.getClass().getResource("a.docx").getPath();

         DataSource attr_ds = new FileDataSource(new File(attr_path));

         DataHandler attr_handler = new DataHandler(attr_ds);

         right.setDataHandler(attr_handler);

         right.setFileName("a.docx");

        

        

         /***************设置邮件内容: 多功能用户邮件 (related)*******************/

         // 4.1 构建一个多功能邮件块

         MimeMultipart related = new MimeMultipart("related");

         // ----> 设置到总邮件快的左侧中

         left.setContent(related);

        

         // 4.2 构建多功能邮件块内容 = 左侧文本 + 右侧图片资源

         MimeBodyPart content = new MimeBodyPart();

         MimeBodyPart resource = new MimeBodyPart();

        

         // 设置具体内容: a.资源(图片)

         String filePath = App_3ImgAndAtta.class.getResource("8.jpg").getPath();

         DataSource ds = new FileDataSource(new File(filePath));

         DataHandler handler = new DataHandler(ds);

         resource.setDataHandler(handler);

         resource.setContentID("8.jpg");   // 设置资源名称,给外键引用

        

         // 设置具体内容: b.文本

         content.setContent("<img src='cid:8.jpg'/>  好哈哈!", "text/html;charset=UTF-8");

        

         related.addBodyPart(content);

         related.addBodyPart(resource);

        

        

        

         // 5. 发送

         Transport trans = session.getTransport();

         trans.connect("zhangsan", "888");

         trans.sendMessage(message, message.getAllRecipients());

         trans.close();

       }

    }

    3. 注意

    Java project。

    如果是web项目,因为javaee自带的有邮件功能,可能存在问题!

    我们要用自己的mail.jar文件功能!  需要删除javaee中mail包!

  • 相关阅读:
    解决:insert Vodafone sim card,open the mms read report,when receive the read report,cann&#39;t download..
    为什么不记录慢速查询?
    [TypeScript] Understand lookup types in TypeScript
    [Angular] How to styling ng-content
    [Http] Understand what an HTTP Request is
    [AngularJS] Directive for top scroll bar
    [SCSS] Write Custom Functions with the SCSS @function Directive
    [SCSS] Loop Over Data with the SCSS @each Control Directive
    [GraphQL] Deploy a GraphQL dev playground with graphql-up
    [Javascript] Different ways to create an new array/object based on existing array/object
  • 原文地址:https://www.cnblogs.com/GJ-ios/p/6037382.html
Copyright © 2011-2022 走看看