zoukankan      html  css  js  c++  java
  • 文件上传组件FileUpload 以及邮箱搭建JavaMail

     文件上传与下载

    1.1 文件上传

    案例:

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

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

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

    文件上传,要点:

    前台:

    1. 提交方式:post

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

    3. 指定表单类型:

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

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

    即:enctype = 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文件,web下面的lib目录中

    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. 文件上传工厂 主要是对Fileitem配置

    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>    

       <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>--%>

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

    <!-- var自动加上 ${pageContext.request.contextPath } -->

    <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);

    }

    }

    恩上面的下载函数我有话说,response.getOutputStream之后,逼得不需要设置,output出去的位置,这一个 都是服务器把后面的工作给做掉了,这样会把问价直接写到客户端对应的端口,别的你不用考虑,下载的时候点击保存之后,会自己快乐的保存下来。这里面有很多画面自己多想想吧。

    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文件功能!  需要删除javaeemail!

    具体做法讲师有提到:首先在左侧的package视图中,找到javaee.jar这个包,ctrl+c复制的就是路径,这个时候,在资源浏览器中,打开上面的路径就可以找到对应的javaee.jar,这个是集成在myeclipse中的,这时候进入这个javaee包,然后删除其中的mail.jat文件即可。

  • 相关阅读:
    单例
    淘宝在数据处理领域的项目及开源产品介绍 | 岭南六少
    数据库垂直拆分,水平拆分利器,cobar升级版mycat
    基于Gtid的mysql主从复制 和 mysql-proxy 读写分离
    几行lua代码计算http包总长度_指甲锉_新浪博客
    使用Lua和OpenResty搭建验证码服务器
    测试比json更快更小的二进制数据传输格式Msgpack [pythono MessagePack 版本]
    使用 HAProxy, PHP, Redis 和 MySQL 轻松构建每周上亿请求Web站点
    nginx+lua+redis实现验证码防采集
    OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能 | 琥珀志
  • 原文地址:https://www.cnblogs.com/OliverZhang/p/6084363.html
Copyright © 2011-2022 走看看