监听器&文件上传和下载

Day19 监听器&文件上传和下载

tomcat里面的三大组件

  1. servlet
  2. filter
  3. 监听器

监听器(Listener)

事件驱动编程

简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数)。
事件驱动编程中核心对象:

  1. 事件源:谁发出事件通知,发出消息;也就是事件主体,比如按钮;
  2. 事件名称:发出什么样的通知的名称,比如鼠标到我头上了,我被别人点了一下;
  3. 事件响应函数:谁对这个这个事件感兴趣,当这个事件发生时要执行什么样的操作;
  4. 事件对象:一般来说,当事件发生时,会产生一个描述该事件的具体对象,包含事件相关信息

什么是监听器

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
监听器也可以说是我们WEB中的一个组件

WEB中有哪些监听器

在这里我们分成两类共6个,一类是作用域生命周期监听器,一类是作用域属性监听器。

作用域生命周期监听器

  • ServletRequestListener:
  • HttpSessionListener:
  • ServletContextListener:

作用域属性监听器

  • ServletRequestAttributeListener:
  • HttpSessionAttributeListener:
  • ServletContextAttributeListener

上传功能

上传准备工作

表单控件:<input type=”file” name=”headImg” />

最后想要的肯定是一个二进制的流
重要:上传时,我们表单的请求类型必需设置成enctype=multipart/form-data
上传的method必需是POST的

步骤:

  1. 准备一个form表单,里面有一个上传,form表单的类型必需是multipart/form-data
  2. 准备一个上传的Servlet,到后台接收传过来的普通表单数据 与 文件(二进制)
  3. 导入相应的FileUpload jar包 (commons-fileupload-1.2.2.jar ,commons-io-1.4.jar)

上传代码

StudentUploadServlet:

@WebServlet("/upload")
public class StudentUploadServlet extends HttpServlet{
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1.接收请求参数  
		Map<String, String> map = new HashMap<String, String>();
		//调用工具类 完成map里面值的封装
		UploadUtil.upload(req, map);
		System.out.println(map);
		
		Student student = new Student();
		
		//通过  BeanUtils map 里面的数据拷贝到student
		
		//调用dao的保存方法
		
		//跳转到list页面
	}
}

UploadServlet:


	private static  String[] arr = {"jpg","png","bmp","gif"};
	
	public static void upload(HttpServletRequest req ,Map<String,String> map) throws ServletException, IOException {
		//检查我们是否有文件上传请求
		boolean isMultipart = ServletFileUpload.isMultipartContent(req);
		if (isMultipart) {
			try {
				//为基于磁盘的文件项创建工厂
				DiskFileItemFactory  factory = new DiskFileItemFactory();
				//设置缓存大小
				factory.setSizeThreshold(1024 * 10 * 5); //50KB 
				//设置临时目录  当文件上传完成以后 就会自己删除
				factory.setRepository(new File("D:/temp")); 
				//创建一个新的文件上传处理程序
				ServletFileUpload upload = new ServletFileUpload(factory);
				//设置上传文件的单个大小
				upload.setFileSizeMax(1024 * 1024* 4);
				//解析请求
				List<FileItem> items = upload.parseRequest(req);
				for (FileItem fileItem : items) {
					//处理普通字段
					if (fileItem.isFormField()) {
						//获取字段名字
					//	System.out.println(fileItem.getFieldName());
						//获取字段上面的值
					//	System.out.println(fileItem.getString());
						map.put(fileItem.getFieldName(), fileItem.getString("UTF-8"));
					}else {
						//fileItem.getName()  获取上传的文件名字
						//System.out.println("文件名字:"+fileItem.getName());
						/*文件存储的地址盘符不能写死
						 * 	上传到系统的自定义目录
						 * */
						String realPath = req.getServletContext().getRealPath("/upload");
						//文件重命名
						fileItem.getName();
						//获取文件的后缀名
						String extension = FilenameUtils.getExtension(fileItem.getName());
						List<String> asList = Arrays.asList(arr);
						// 如果上传的文件后缀名不在集合里面
						if (!asList.contains(extension)) {
							//1.抛异常
							throw new Exception("请上传图片类型的文件");
							//2.给前台提示
						}
						//自己重新定义一个不会重复的名字  方案1.UUID  2.时间戳
						//String filename = UUID.randomUUID().toString();
						String filename = String.valueOf(System.currentTimeMillis());
						//String filename =System.currentTimeMillis()+"";
						
						map.put(fileItem.getFieldName(), "/upload/"+filename+"."+extension);
						//处理文件
						File fileupload = new File(realPath,filename+"."+extension);
						//判断文件夹是否存在
						if (!fileupload.getParentFile().exists()) {
							//如果有不存在的文件夹,就创建文件夹
							fileupload.getParentFile().mkdirs();
						}
						//把上传的数据写到指定的文件中
						fileItem.write(fileupload);
					}
				}
				
			} catch (FileUploadBase.FileSizeLimitExceededException e) {
				//如果文件过大  单独处理 --可以去自定义一个异常  告诉用户文件过大    --给前台提示 当前上传的文件过大
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		
	}


上传细节处理

  • IE低版本的文件名称Bug解决
  • 上传文件的名称冲突问题
  • 将文件存在本项目中
  • 普通字段的获取
  • 设置缓存大小与临时目录
  • 设置文件大小
    在上述代码中体现

下载功能

<a href="/download/aa.rar">aa.rar</a><br />
<a href="/download/美女.rar">美女.rar</a><br />
<a href="/download/用户.rar">用户.rar</a><br />

神奇的事情发生了! 直接就可以下载! 简单得大家都不敢相信。
行了,这种下载方式在一些网站中也在使用,但是它有相应的问题:
第一:如果你的文件是一个图片,它是不会下载的,因为浏览器对于它自己认识的文件会去尝试打开(听说IE低版本(IE6)连压缩文件都要尝试一下)
第二:现在大家上过很多论坛什么的,咱们下载文件还需要判断用户是否登录,有的时候还会进行相应的扣分吧!这个下载方式也没有办法实现

好处:简单,没有中文乱码问题


重要!!!
//设置响应的文件类型
//告诉浏览器文件应该被下载,而不是被直接打开(IE6直接打开)
// text/html;charset=utf-8
resp.setContentType("application/x-msdownload");

// 两个参数:第一个参数相当于拿到程序中的真实文件 第二个参数拿到我们的响应输出流 然后通过流将文件从程序拷备到客户端
Files.copy(Paths.get(file.getAbsolutePath()), resp.getOutputStream());

发布了54 篇原创文章 · 获赞 9 · 访问量 953

猜你喜欢

转载自blog.csdn.net/qq_40629521/article/details/103713575
今日推荐