JavaEE中级.20190610.文件上传下载.过滤器.监听器.

一.文件上传下载

     1.文件上传

              文件上传涉及到前台页面的编写和后台服务器端代码的编写,前台发送文件,后台接收 并保存文件,这才是一个完整的

        文件上传。

         1) 前台页面
                    在做文件上传的时候,会有一个上传文件的界面,首先我们需要一个表单,并且表单的 请求方式为 POST;其次我

们的 form 表单的 enctype 必须设为”multipart/form-data” 即 enctype="multipart/form-data" 意思是设置表单的MIME 编码。默认情况下这个编码格式 是 ”application/x-www-form-urlencoded”,不能用于文件上传;只有使用了multipart/form-data 才能完整地传递文件数据。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
	<form action="userServlet" method="post">
		姓名:<input type="text" name="uname" id="uname" /> <br/>
		密码:<input type="password" name="upwd" id="upwd" /> <br/>
		<input type="button" value="登录" onclick="checkForm()" />
		<span id="msg" style="font-size:12px;color:red"></span>
		<input type="hidden" name="actionName" value="form" />
	</form>
</body>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
<script type="text/javascript">
	/*
	 * 验证表单
	 */
	function checkForm(){
		// 获取用户名
		var uname = $("#uname").val();
		// 判断是否为空
		if (uname.length < 1) {
			$("#msg").html("姓名不能为空!");
			return;
		}
		//  获取密码
		var upwd = $("#upwd").val();
		// 判断是否为空
		if (upwd.length < 1) {
			$("#msg").html("密码不能为空!");
			return;
		}
		
		// 提交表单
		$("form").submit();
	}
</script>
</html>

         2) 后台 commons-fileupload 的使用
                    首先需要导入第三方jar 包,http://commons.apache.org/ 下 载commons-io 和 commons-fileupload 两个jar 的资源。解压并导入到项目中。commons-fileupload.jar 是文件上传的核心包 commons-io.jar 是 filefupload 的依赖包,同时又是一个工具包。             

                        

               介绍一下使用到的几个核心类

                 DiskFileItemFactory – 设置磁盘空间,保存临时文件。只是一个工具类
                 ServletFileUpload – 文件上传的核心类,此类接收 request,并解析
                 ServletFileUpload.parseRequest(request); – List 解析 request
                 1、 创建一个 DiskFileItemFactory 工厂类,并制定临时文件和大小
                 2、 创建 ServletFileUpload 核心类,接收临时文件,做请求的转换
                 3、 通过 ServletFileUpload 类转换原始请求,得到 FileItem 集合
                 4、 遍历集合中的各个元素并处理
                 5、 判断每个元素是否是普通表单项,如果是则按照普通表单项处理
                 6、 如果不是普通表单项,则是文件,通过处理的方式进行处理(上传)

public class UploadSource extends HttpServlet {
    protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
        // 设定编码,可以获取中文文件名
        req.setCharacterEncoding("UTF-8");
        // 获取tomcat下的upload目录的路径
        String path = getServletContext().getRealPath("/upload");
        // 临时文件目录
        String tempPath = getServletContext().getRealPath("/temp");
        // 检查我们是否有文件上传请求
        // boolean isMultipart = ServletFileUpload.isMultipartContent(req);
        // 1、声明DiskFileItemFactory工厂类,用于在指定磁盘上设置一个临时目录
        DiskFileItemFactory disk = new DiskFileItemFactory(1024 * 10, new
File(tempPath));
        // 2、声明ServletFileUpload,接收上面的临时文件。也可以默认值
        ServletFileUpload up = new ServletFileUpload(disk);
        // 3、解析request
        try {
            List<FileItem> list = up.parseRequest(req);
            if (list.size() > 0) {
                for (FileItem file : list)
                    // 判断是否是普通的表单项
                    if (file.isFormField()) {
                        String fieldName = file.getFieldName();
                        // 中文乱码,此时还需要指定获取数据的编码方式
                        // String value = file.getString();
                        String value = file.getString("UTF-8");
                        System.out.println(fieldName + "=" + value);
                    } else { // 说明是一个文件
                        // 获取文件本身的名称
                        String fileName = file.getName();
                        System.out.println(file.getFieldName());
                        // 处理文件名称
                        fileName =
fileName.substring(fileName.lastIndexOf("\\") + 1);
                        System.out.println("old Name : " + fileName);
                        // 修改名称
                        String extName =
fileName.substring(fileName.lastIndexOf("."));
                        String newName =
UUID.randomUUID().toString().replace("-", "") + extName;
                        // 保存新的名称,并写出到新文件中
                        file.write(new File(path + "/" + newName));
                        System.out.println("文件名是:" + fileName);
                        System.out.println("文件大小是:" + file.getSize());
                        file.delete();
                    }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
}
}

     2. 文件下载
               文件下载即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。第一种是通过超链接本身的特性来下载;第二种是通过手动写出来下载。
            1) 超链接下载
                       当我们在 HTML 或 JSP 页面中使用标签时,原意是希望能够进行跳转,但当超链接遇到浏览器不识别的动态网页时则会自动下载。例如超链接下载但当遇见浏览器能够直接显示的资源,浏览器就会默认显示出来,比如 txt,png,jpg 等。当然我们也可以通过 download 属性规定浏览器进行下载。但有些浏览器并不支持。

                默认下载

                 指定 download 属性下载

               这里,download 也可以不写任何信息,会自动使用默认文件名。这样当用户打开浏览 器点击链接的时候就会直接下载文件。

        2) 后台实现下载
      Step1:需要通过 HttpServletResponse.setContentType 方法设置 Content-type头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 ”application/octet-stream” 或 ”application/x-msdownload” 等
     Step2:需要通过 HttpServletResponse.setHeader 方法设置Content-Disposition 头的值 为”attachment;filename=文件名”
    Step3: 读取下载文件,调用HttpServletResponse.getOutputStream 方法返回的OutputStream 对象来向客户端写入附件内容。

public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        // 获取文件下载路径
        String path = getServletContext().getRealPath("/") + "download/";
        String fileName = req.getParameter("filename");
        File file = new File(path + fileName);
        if (file.exists()) {
            // 设置相应类型 application/octet-stream
            resp.setContentType("application/x-msdownload");
            // 设置头信息
            resp.setHeader("Content-Disposition", "attachment;filename=" +
fileName);
            InputStream is = new FileInputStream(file);
            ServletOutputStream os = resp.getOutputStream();
            byte[] car = new byte[1024];
            int len = 0;
            while ((len = is.read(car)) != -1) {
                os.write(car, 0, len);
            }
            // 关闭流、释放资源
            os.close();
            is.close();
        } else {
            System.out.println("文件不存在,下载失败!");
        }
    }
}

二、过滤器

        1.介绍
                 Filter 即为过滤,用于在 Servlet 之外对 Request 或者 Response 进行修改。它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理。使用 Filter 的完整流程: Filter 对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再 对服务器响应进行后处理。在一个 web 应用中,可以开发编写多个 Filter,这些 Filter 组合 起来称之为一个 Filter 链。

                    

                    若是一个过滤器链:先配置先执行(请求时的执行顺序);响应时: 以相反的顺序执行。在 HttpServletRequest 到达 Servlet 之前,拦截客户的 HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改 HttpServletRequest 头和数据。在HttpServletResponse 到达客户端之前,拦截 HttpServletResponse。根据需要检查 HttpServletResponse,也可以修改 HttpServletResponse 头和数据。

       2. 实现
              我们可以通过实现一个叫做javax.servlet.Fileter 的接口来实现一个过滤器,其中定义了 三个方法,init(), doFilter(), destroy()分别在相应的时机执行。后期观察生命周期。 Filter 的实现只需要两步:
               Step1: 编写 java 类实现 Filter 接口,并实现其 doFilter 方法。
              Step2: 在 web.xml 文件中对编写的 filter 类进行注册,并设置它所能拦截的资源。

                       

                       

               Filter 接口中有一个 doFilter 方法,当开发人员编写好 Filter,并配置对哪个 web 资源进行拦截后,Web 服务器每次在调用 web 资源的 service 方法之前,都会先调用一下 filter 的 doFilter 方法。因此可以达到如下效果:
              调用目标资源之前,让一段代码执行。
              是否调用目标资源(即是否让用户访问 web 资源)。
              web 服务器在调用 doFilter 方法时,会传递一个 filterChain 对象进来,filterChain 对象是 filter 接口中最重要的一个对象,它提供了一个 doFilter 方法,开发人员可以根据需求决定 是否调用此方法,调用该方法,则 web 服务器就会调用 web 资源的 service 方法,即 web 资源就会被访问,否则 web 资源不会被访问。(本质是放行,调用doFilter 方法后,即请求可以到达资源)

                            

                         url-pattern 的配置:
                         ①配置具体路径/index.html/TestServlet.do
                         ②带有通配符的配置*.do /* /user/* *.html *.jsp

       3. 过滤器执行的顺序
                 通过观察 web.xml 中的配置和各个filter 的执行顺序,找出filter 执行先后的依据。根据之前观察 Servlet 生命周期的的方式,观察一下过滤器的生命周期。

三、监听器

        1. 介绍
                  web 监听器是一种 Servlet 中的特殊的类,它们能帮助开发者监听 web 中的特定事件, 比如 ServletContext,HttpSession,ServletRequest 的创建和销毁;变量的创建、销毁和修改等。 可以在某些动作前后增加处理,实现监控。例如可以用来统计在线人数等。
         2. 实现
                   监听器有三类8 种:⑴监听生命周期:实现接口ServletRequestListener、HttpSessionListener 、 ServletContextListener⑵监听值的变化:实现接口ServletRequestAttributeListener、HttpSessionAttributeListener、ServletContextAttributeListener ⑶针对 session 中的对象:监听 session 中的java 对象(javaBean) 是 javaBean 直接实现监听器 的接口。这里我们只做一个简单的演示。假设我们想做一个对在线人数的监控。
               Step1:创建一个监听器,需要实现某种接口,根据需求选取HttpSessionListener
              Step2:在 web.xml 中配置该监听器
              创建一个类,并实现 HttpSessionListener 接口,用来检测 Session 的创建和销毁。 在类中定义一个成员变量用来存储当前的 session 个数。

                     

              在 web.xml 中配置该监听器,让监听器生效

                     

              做一个测试的 Servlet 用来登陆,和显示当前在线人数

                     

               访问并测试结果

                     

 

 

 

 

 

 

 

 

 

                

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值