JavaEE三大神器之监听器

监听器

一、Listener 监听器

1. 概述

  • Servlet技术中三大组件之一 - Servlet Filter Listener
  • Servlet技术规范中sun预先定义了八大监听器用来监听web开发中对应的事件
  • 监听器可以用来监听web应用执行过程中相关的事件 来进行对应的处理

2. 开发监听器步骤

  1. 写一个类实现指定监听器接口
  2. 在web.xml文件中配置监听器

3. 监听三大作用域创建和销毁的监听器

  1. ServletContextListener:该监听器负责监听ServletContext的创建和销毁

     生命周期:在web应用启动时创建出来之后一直驻留在内存中唯一的代表当前web应用直到web应用移除出容易或服务器关闭时随着web应用的销毁ServletContext对象跟着被销毁
     作用范围:整个web应用范围
     主要功能:在整个web应用范围内 整个web应用存活期间 共享数据
    
  2. HttpSessionListener:负责监听HttpSession对象的创建和销毁事件

     生命周期:在第一次调用request.getSession()时创建  自杀 - session.invalidate 超时 - 30分钟 意外身亡 - 服务器非正常关闭
     作用范围:整个会话
     主要功能:在整个会话范围内 整个会话的生命周期期间 共享数据
    
     钝化:在服务器正常关闭时 仍然在存活期间的session 会被序列化后保存在tomcat的work目录下 这个过程称之为session的钝化
     活化:在服务器正常启动时 会将钝化的session再恢复到内存中 继续使用 这个过程称之为session的活化
    
  3. ServletRequestListener

     生命周期:请求开始时创建 请求结束时销毁
     作用范围:整个请求
     主要功能:在请求过程中 在请求范围内 共享数据
    

4.监听三大作用域中属性增加、修改或减少的监听器

  1. ServletContextAttributeListener
  2. HttpSessionAttributeListener
  3. ServletRequestAttributeListener

5. 使javabean自己感知 自己在session域中状态变化的监听器

  1. HttpSessionBindingListener - 使javabean自己感知自己在session域中 被加入 或 移除的 状态变化的监听器
  2. HttpSessionActivationListener - 使javabean自己感知自己在session域中 随着session被钝化 活化 状态变化的监听器
  3. 这两个监听器比较特殊 不需要单独写类来实现 也不需要在web.xml中进行配置 只需要让javabean自己来实现即可

6.EasyMall中监听器的应用

  • 开发EasyMallServletContextListener
  • 在ServletContext创建时 向 ServletContext域中增加 app 属性 值为应用的路径 在ServletContext销毁时删除该属性 这样 以后需要在jsp页面中写应用路径时 直接写$(app)即可

二、文件上传

1.文件上传概述

  • 在web开发中经常需要从客户端向服务器上传文件,如:上传照片、上传新闻图片、上传附件等等。这些都需要通过WEB开发中的文件上传技术实现。

2. 文件上传步骤

  • 提供一个带有文件上传项的表单
  • 文件上传的输入框必须有name属性才能被上传
  • 文件上传的表单必须是post提交
  • 文件上传的表单必须设置enctype=multipart/form-data

在Servlet中处理文件上传相关的逻辑
方式1:
可以通过javaee原生的api request.getInputStream 来获取请求中实体内容的流
获取到流中的数据后 解析 处理 – 非常麻烦

方案2:
	使用开源工具实现
	Apache提供的文件上传包 - Commons-fileupload

3.Commons-fileupload

  • 下载并导入对应的包
    1. Commons-fileupload
    2. commons-io

(1)文件上传工厂 DiskFileItemFactory

	public DiskFileItemFactory(int sizeThreshold, java.io.File repository)
    // sizeThreshold - 指定内存缓冲区的大小
	//repository - 指定临时文件存放的位置
	/*文件上传 时需要将请求的实体内容 全部读取后 才能做处理
	此时需要将实体内容缓冲起来 内存缓冲快 但是耗费内存 文件缓冲慢 但是可以存放大量数据
	所以此处提供了两个选项 如果数据大小小于sizeThreshold则使用内存做缓冲 速度快  如果文件大小超过了该限制则在repository指定的位置下创建临时文件来缓冲数据*/

(2)上传文件核心类 ServletFileUpload

ServletFileUpload fileUpload = new ServletFileUpload(factory);
	//判断当前提交数据表单是否是一个enctype为multipart/form-data类型的表单
	boolean isMultipartContent(HttpServletRequest request)
	//指定处理文件名时使用的编码集
	setHeaderEncoding(java.lang.String encoding)
	//控制单个文件大小最大值
	setFileSizeMax(long fileSizeMax)
	//控制总的文件大小最大值
	setSizeMax(long sizeMax) 
	//解析request对象 获取 FileItem的集合
	List<FileItem> parseRequest(HttpServletRequest request)
	//设置上传文件监听器
	setProgressListener(ProgressListener pListener)

(3)文件上传项 FileItem

List<FileItem> parseRequest(HttpServletRequest request)
    //判断当前FileItem是不是一个普通字段项 如果返回true表示这是一个普通字段项 返回false表示是一个文件上传项
    boolean isFormField()
    //如果是普通字段项
    String getFieldName() //获取字段项的名称
    String getString() //获取字段项的值
    String getString(String encode) //获取字段项的值
    //如果是文件上传项
    String getName() //获取文件名
    InputStream getInputStream() //获取文件内容的流
    delete() //删除临时文件

(4)ie上传文件 文件名 Bug 处理

if(fname.contains("\\")){
	fname = fname.substring(fname.lastIndexOf("\\"));
}

(5)文件上传保存位置问题
文件上传保存的位置一定不能被外界直接访问 防止 用户用户浏览器访问 下载资源 或执行jsp恶意代码
要么保存在WEB-INF下保护起来 要么放在本地磁盘 其他位置 保证通过浏览器无法直接访问

(6)上传文件重名问题
多个上传名称相同时 文件会发生覆盖
应该想办法让文件名 尽量不要重复 - 在文件名的前面拼接UUID来保证文件名绝对不会重复

(7)上传文件目录下文件过多 - hash分目录存储
一个文件夹下文件过多 会造成 访问缓慢 甚至有可能无法访问
所以 应该想办法 将这些文件分目录存储

计算文件名的hash - 散列
将hash值转换为16进制的字符串 - 共8位 值0-9 a-f
将这个hash字符串截取出每一位作为一级目录 
最终将上文件放置到8级hash目录下  共有  16^8 个可能的文件夹 分目录存放文件 从而保证一个文件夹文件不会过多

(8)文件上传进度监听
upload.jsp页面中 为表单提交事件增加函数触发 增加定时器 每隔一段时间 通过ajax发送是那个请求 访问服务器 获取最新的文件上传进度 展示到页面

$(document).ready(function(){
	$("#f").submit(function(){
		window.setInterval(function(){
		$.get("${pageContext.request.contextPath }/servlet/UploadProgressServlet", function(data){
			$("#in_div").width(data);
		});
		}, 10);
	})
});
  • UploadServlet中 为问件上传注册监听器 计算各种指标 并且将计算的指标 存入session

  • UploadProgressServlet中 从session中获取上传进度信息 作为响应发回给ajax访问

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值