大数据正式22

来源:互联网 发布:万信达软件官网 编辑:程序博客网 时间:2024/06/16 11:53

大数据正式22

监听器

  • 概述
    • Listener--监听器
    • Servlet技术中的三大组件之一【Servlet、Filter、Listener】
    • 简单、应用少
    • 监听器可以用来监听web应用执行过程中的相关的事件,来进行对应的处理
  • 应用
    1. 写一个类实现监听器接口
    2. web中配置
  • 监听三大作用域创建和监听器

    1. ServletContextListener

      • 生命周期:web部署到下线
      • 作用范围:整个web应用
      • 主要功能:整个web应用中共享数据
      • 例子

        package com.peng.listener;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;public class MyServletContextListener implements ServletContextListener {    public void contextDestroyed(ServletContextEvent arg0) {        System.out.println("context Destory");    }    public void contextInitialized(ServletContextEvent arg0) {        System.out.println("context Init");    }}

        <!-- 监听器的配置 --><listener>    <listener-class>com.peng.listener.MyServletContextListener</listener-class></listener>
    2. HttpSessionListener

      • 生命周期:第一次调用request.getSession()
      • 作用范围:整个web应用的额会话周期
      • 主要功能:整个会话的生命周期共享数据

        package com.peng.listener;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;public class MySessionListener implements HttpSessionListener {    public void sessionCreated(HttpSessionEvent arg0) {        System.out.println("session create!!!");    }    public void sessionDestroyed(HttpSessionEvent arg0) {        System.out.println("session destory!!!");    }}

        <!-- 监听器的配置 --><listener>    <listener-class>com.peng.listener.MySessionListener</listener-class></listener>
    3. ServletRequestListener

      • 生命周期:一次请求和一次响应的过程中
      • 作用范围:一次请求和一次响应的过程中
      • 主要功能:一次请求和一次响应的过程中共享数据

        package com.peng.listener;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;public class MyRequestListener implements ServletRequestListener {    public void requestDestroyed(ServletRequestEvent arg0) {        System.out.println("destory ServletRequestListener");    }    public void requestInitialized(ServletRequestEvent arg0) {        System.out.println("init ServletRequestListener");    }}

        <!-- 监听器的配置 --><listener>    <listener-class>com.peng.listener.MyRequestListener</listener-class></listener>
    4. ServletContextAttributeListener

      package com.peng.listener;import javax.servlet.ServletContextAttributeEvent;import javax.servlet.ServletContextAttributeListener;public class MyServletContextListener implements        ServletContextAttributeListener {    public void attributeAdded(ServletContextAttributeEvent arg0) {    }    public void attributeRemoved(ServletContextAttributeEvent arg0) {    }    public void attributeReplaced(ServletContextAttributeEvent arg0) {        // getValue为旧值        // 获取新值 arg0.getServletContext().getAttribute(arg0.getName());    }}
    5. HttpSessionAttributeListener

      package com.peng.listener;import javax.servlet.http.HttpSessionAttributeListener;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;public class MySessionAttributeListener implements HttpSessionAttributeListener {    public void attributeAdded(HttpSessionBindingEvent arg0) {    }    public void attributeRemoved(HttpSessionBindingEvent arg0) {    }    public void attributeReplaced(HttpSessionBindingEvent arg0) {        // TODO Auto-generated method stub    }}
    6. ServletRequestAttributeListener

      package com.peng.listener;import javax.servlet.ServletRequestAttributeEvent;import javax.servlet.ServletRequestAttributeListener;public class MyRequestSAttributeListener implements        ServletRequestAttributeListener {    public void attributeAdded(ServletRequestAttributeEvent arg0) {    }    public void attributeRemoved(ServletRequestAttributeEvent arg0) {    }    public void attributeReplaced(ServletRequestAttributeEvent arg0) {        // TODO Auto-generated method stub    }}
    7. 使javabean自己感知在session域中的变化HttpSessionBindingListener(加入,移除)

      • 注:javabean实现这个接口,重写方法;web.xml中无须配置

        package compeng.javabean;import java.io.Serializable;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionBindingListener;public class PersonBinding implements Serializable, HttpSessionBindingListener {    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public void valueBound(HttpSessionBindingEvent arg0) {        // 加入    }    public void valueUnbound(HttpSessionBindingEvent arg0) {        // 移出    }}
    8. 使javabean自己感知在session域中的变化HttpSessionActivationListener(钝化,活化)

      • 注:javabean实现这个接口,重写方法;web.xml中无须配置
      • 注:javabean记得实现序列化接口
      • 活化回来时,对象不是同一个,只是携带的信息一样而已

        package compeng.javabean;import java.io.Serializable;import javax.servlet.http.HttpSessionActivationListener;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionBindingListener;import javax.servlet.http.HttpSessionEvent;class PersonBinding implements Serializable, HttpSessionActivationListener {    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public void sessionDidActivate(HttpSessionEvent arg0) {        // 序列化    }    public void sessionWillPassivate(HttpSessionEvent arg0) {        // 反序列化    }}

钝化和活化

  • 钝化
    • 在服务器正常关闭时,仍然存活的session会被钝化到work目录下
  • 活化
    • 在服务器正常开启时,将work目录下session.ser文件重写加载到服务器

EasyMall监听器的使用

  • EasyMall应用开启时设置项目路径到“app”变量中
  • EasyMall应用关闭时销毁“app”变量
  • 例子

    package com.easymall.listener;import javax.servlet.ServletContextEvent;public class ServletContextListener implements        javax.servlet.ServletContextListener {    public void contextDestroyed(ServletContextEvent arg0) {        // 将项目路径移除        arg0.getServletContext().removeAttribute("app");    }    public void contextInitialized(ServletContextEvent arg0) {        // 将项目的路径存到app这个变量中        arg0.getServletContext().setAttribute("app",                arg0.getServletContext().getContextPath());    }}

文件上传

  • 步骤
    1. 带有文件上传的表单
      1. 必须有name
      2. 必须为post方式
      3. enctype的参数配置:multipart/form-data
    2. 在servlet写相应的逻辑【麻烦的逻辑】
      1. 获取流
      2. 变成字符串
      3. 切分字符串根据头信息
      4. 获取想要的文件
      5. enctype的参数配置:multipart/form-data
    3. 在servlet写相应的逻辑【简单的方式】
      1. Commaons-fileupload.jar包;commans-io.jar包
      2. 过程
        1. 创建文件上传工厂DiskFileItemFactory【内存缓冲区大小;文件临时存放目录】【文件全部传入才能做处理:放内存中--速度快但是占资源;放文件--速度慢,但是文件大小可以基本不受限制】【超过内存缓冲区,就执行文件临时存放目录】
        2. 创建文件上传的核心类ServletFileUpload
          1. isMultipartCotent(HttpServletRequest req)//判断当前上传的表单是否是multipart/form-data
          2. List parseRequest(HttpServletRequest req)//将请求头解析成文件的列表
          3. setFileSizeMax(long size)//控制文件上传的大小(Byte)
          4. setSizeMax(long size)//控制总的文件上传的最大值
        3. FileItem:文件上传项目--遍历item分别做处理
          1. isFormFiled判断当前FileItem是不是一个普通字段项----返回false为文件上传项
            1. 普通字段项
              1. getFieldName//获取字段项的名称
              2. getString//字段项的值
            2. 文件上传项
              1. getName//获取文件的名称
              2. getInputStream//获取文件的输入流
        4. 如果是文件,将获取到FileItem的输入流写入到文件的输出流中
      3. 遇到的问题
        • 文件名乱码(文件名称是中文名时)
          • 上传文件核心类的设置编码:setHeaderEncoding(encode)
        • 文件内容的乱码
          • response.setHeaderEncoding("utf-8")解决不了乱码
          • FileItem.getString(encode)
        • 临时文件未删除
          • FileItem.delete(记得该关的流关掉,要不删不了文件)
        • IE浏览器上传
          • Item.getName获取到的文件是全路径名(例如:C://a/b/c.txt)
          • 问题解决--只获取文件名
        • 文件上传保存的位置问题
          • 为了安全--文件保存的位置一定不能让外界直接访问
            1. Web-Inf下
            2. 本地文件的位置外界无法访问到
        • 文件重复--同名文件的覆盖
          • 尽量让文件名不要重复UUID(参考:时间+CPU时钟+。。。)
          • UUID.randomUUID().toString
        • 上传目录下文件过多:访问缓慢、甚至无法访问
          • 分目录存放
          • Integer.toHexString(int)+ 不够八位补0【HashCode不一定是唯一的】
          • 哈希特点:散列(相同二进制得到的数据相同)
          • 例:a/1/b/3/1/1/4/b/1bacbaaa.png
          • 总共产生的文件夹168
      4. 文件上传进度
        • ServletFileUpload.setProgressListener(ProgressListener pro);

简单例子

  • index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head></head><body bgcolor="#00ff00" text="#ffffff">${requestScope.message}</body></html>
  • fileUp.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>文件上传</title></head><body bgcolor="#ff00ff" text="#00ffff">    <center>        <h1>name:</h1>        <input type="text" name="name" />        <h1>请选择文件:</h1>        <form action="FileUpServlet" method="post"            enctype="multipart/form-data">            <input type="file" name="file" /> <input type="submit" value="上传文件" />        </form>    </center></body></html>
  • FileUpServlet

    package com.peng.ser;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;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.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;public class FileUpServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doPost(request, response);    }    /* 上传文件逻辑 */    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全        String savePath = this.getServletContext().getRealPath(                "/WEB-INF/upload");        File file = new File(savePath);        // 判断上传文件的保存目录是否存在        if (!file.exists() && !file.isDirectory()) {            System.out.println(savePath + "目录不存在,需要创建");            // 创建目录            file.mkdir();        }        // 消息提示        String message = "";        try {            // 使用Apache文件上传组件处理文件上传步骤:            // 1、创建一个DiskFileItemFactory工厂            DiskFileItemFactory factory = new DiskFileItemFactory();            // 2、创建一个文件上传解析器            ServletFileUpload upload = new ServletFileUpload(factory);            // 解决上传文件名的中文乱码            upload.setHeaderEncoding("UTF-8");            // 设置文件的大小            upload.setFileSizeMax(2 * 1024 * 102);// 设置单个文件的最大值            upload.setSizeMax(50 * 1024 * 1024);// 设置总的文件的总的大小            // 3、判断提交上来的数据是否是上传表单的数据            if (!ServletFileUpload.isMultipartContent(request)) {                // 按照传统方式获取数据                return;            }            // 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项            List<FileItem> list = upload.parseRequest(request);            for (FileItem item : list) {                // 如果fileitem中封装的是普通输入项的数据                if (item.isFormField()) {                    String name = item.getFieldName();                    // 解决普通输入项的数据的中文乱码问题                    String value = item.getString("UTF-8");                    // value = new String(value.getBytes("iso8859-1"),"UTF-8");                    System.out.println(name + "=" + value);                } else {// 如果fileitem中封装的是上传文件                        // 得到上传的文件名称,                    String filename = item.getName();                    System.out.println(filename);                    if (filename == null || filename.trim().equals("")) {                        continue;                    }                    // 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:                    // c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt                    // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分                    filename = filename                            .substring(filename.lastIndexOf("\\") + 1);                    // 获取文件名的UUID                    String uuid_fileName = UUID.randomUUID().toString() + "_"                            + filename;                    // 哈希目录--利用文件的名称生成8层文件夹                    String hashCod_8 = Integer.toHexString(uuid_fileName                            .hashCode());                    while (hashCod_8.length() < 8) {                        hashCod_8 = "0" + hashCod_8;                    }                    for (int i = 0; i < hashCod_8.length(); i++) {                        savePath += "\\" + hashCod_8.charAt(i);                    }                    File dir = new File(savePath);                    dir.mkdirs();                    // 获取item中的上传文件的输入流                    InputStream in = item.getInputStream();                    // 创建一个文件输出流                    FileOutputStream out = new FileOutputStream(savePath + "\\"                            + uuid_fileName);                    // 创建一个缓冲区                    byte buffer[] = new byte[1024];                    // 判断输入流中的数据是否已经读完的标识                    int len = 0;                    // 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据                    while ((len = in.read(buffer)) != -1) {                        // 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"                        // + filename)当中                        out.write(buffer, 0, len);                    }                    // 关闭输入流                    in.close();                    // 关闭输出流                    out.close();                    // 删除处理文件上传时生成的临时文件                    item.delete();                    message = "文件上传成功!";                }            }        } catch (Exception e) {            message = "文件上传失败!";            e.printStackTrace();        }        request.setAttribute("message", message);        request.getRequestDispatcher("/index.jsp").forward(request, response);    }}

加入进度显示的文件上传

  • 原生js+原生ajax
    • http://www.jb51.net/article/70521.htm
  • 超级棒的一篇文章
    • http://m.blog.csdn.net/liuzuochen/article/details/1516522
原创粉丝点击