zoukankan      html  css  js  c++  java
  • Servlet基础之过滤器、监听器、文件上传下载


    考虑到这些东西已经不被常用了,就把以前的笔记翻上来应付下好了,暂不炒冷饭。

    Filter(过滤器)

    过滤器

    过滤器的生命周期

    在服务器启动的时候构造过滤器对象并且调用初始化方法。
    在访问到映射路径时调用过滤器的过滤方法(doFilter)。
    销毁的时候或者Reloading的时候调用过滤器的销毁方法.

    登录过滤器

    1. 先强转request和response的对象类型
    2. 获取uri的路径
    3. 判断uri路径是否符合条件--符合条件则放行
    4. 不符合条件则判断session中是否有用户登录凭证--有则放行
    5. 没有则重定向

    编码过滤器

    1. 把处理编码的代码抽取到过滤器中
      • req.setCharacterEncoding("utf-8");
      • 只针对post请求的编码处理
    2. 针对get的请求有2种
      1. 修改服务器的编码格式
      2. 编写包装类
    3. 多个过滤器的过滤顺序
      • 过滤器的过滤顺序跟web.xml的配置有关。
      • 放行后的代码则是服务器响应给客户端的时候执行,执行顺序与过滤顺序相反。

    其他

    过滤器是"链"在容器的处理过程中的。

    这就意味着它们会在servlet处理器之前访问一个进入的请求,并且在外发响应信息返回到客户前访问这些响应信息。
    这种访问使得过滤器可以检查并修改请求和响应的内容。

    关于web.xml

    Fiter的注册映射路径一般是/* 代表通配所有的路径。
    用中间抽象类时要注意web.xml不能有该抽象类的注册,否则会默认实例该类,但抽象类不能实例化。


    Listener(监听器)

    监听器就是监听某个域对象的的状态变化的组件

    监听器的相关概念

    • 事件源:被监听的对象(三个域对象)
      • request
      • session
      • servletContext
    • 监听器:监听事件源对象事件源对象的状态的变化都会触发监听器(6+2)。
    • 注册监听器:将监听器与事件源进行绑定。
    • 响应行为:监听器监听到事件源的状态变化时所涉及的功能代码(程序员编写代码)。

    监听器有哪些

    • 第一维度按照被监听的对象划分:
      • ServletRequest域
      • HttpSession域
      • ServletContext域
    • 第二维度按照监听的内容分:
      • 监听域对象的创建与销毁的
      • 监听域对象的属性变化的

    监听三大域对象的创建与销毁

    监听三大域对象的监听器分别是:

    • ServletContextListener
    • HttpSessionListener
    • ServletRequestListener
    监听器的编写步骤(重点):
    1. 编写一个监听器类去实现监听器接口。
    2. 覆盖监听器的方法。
    3. 需要在web.xml中进行配置—注册。
    监听ServletContext域的创建与销毁的监听器ServletContextListener
    • Servlet域的生命周期

      • 何时创建:服务器启动创建
      • 何时销毁:服务器关闭销毁
    • ServletContextListener监听器的主要作用

      • 初始化的工作:初始化对象、初始化数据(加载数据库驱动、连接池的初始化)
      • 加载一些初始化的配置文件(spring的配置文件)
      • 任务调度(定时器—Timer/TimerTask)
    监听Httpsession域的创建于销毁的监听器HttpSessionListener
    • HttpSession对象的生命周期
      • 何时创建:第一次调用request.getSession时创建
      • 何时销毁:服务器关闭销毁、session过期(默认30分钟,修改默认的30分钟是在Tomcat的web.xml,修改当前项目的过期时间是在自己项目的web.xml中)、手动销毁。
    • HttpSessionListener监听器的主要作用
      • 由于每次访问网站都会默认创建session对象(jsp页面中page指令中的session属性默认为true,即被访问时创建session),可以用于计数网站访问过的人
    监听ServletRequest域创建与销毁的监听器ServletRequestListener
    • ServletRequest的生命周期
      • 创建:每一次请求都会创建request
      • 销毁:请求结束
    • 用法同上

    其他

    剩余四分之三的知识点没写 (我也不知道几年前的我为什么没写,虽然现在我也不想写,后面写过Spring后再讲)


    文件上传下载

    其实都是旧代码了,没什么实际用处,辣鸡代码不看也罢

    上传

    1. 修改项目设置
      • 修改图片上传的目录位置
    2. 修改form表单属性
      • 提交方式为:Post
      • 添加属性为:enctype="multipart/form-data"
      • 上传文件的type为:file
      • 上传文件要设置name才能在后台获得
    3. 导包
      • 对于文件上传,浏览器是以流的形式提交到服务器端的
      • 如果直接用输入流解析请求参数会比较麻烦,一般采用apache提供的jar包组件:
        • commons-fileupload-1.2.2.jar
        • commons-io-2.2.jar
    4. Servlet
      1. 通过jar包实例化 磁盘工厂 对象
      2. 实例化一个 文件上传解析器,在构造方法中传递工厂对象
      3. 解决上传文件名的中文乱码问题
      4. 创建一个map/对象,用于存放表单数据
      5. 通过解析器解析前端发送的复合表单数据,返回一个集合
      6. 遍历这个集合,判断是否为非文本数据
      7. 使用工具包——存储在服务器路径下(注意解决重名问题)
        • 提示用户修改名字
        • 通过时间生成目录
        • 通过UUID生成唯一文件名
      8. 处理表单信息
      9. 关流

    假设有一个表单提交要上传图片

        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("UTF-8");
        
        HashMap<String, String> map = new HashMap<>();
        List<FileItem> list = upload.parseRequest(request);
        for(FileItem item :list){
            //判断是否为非文本数据
            if (!item.isFormField()) {
                ...
            }
        }
        
        //1.通过全局对象获取绝对路径
        String path = getServletContext().getRealPath("Upload");
        File file = new File(path);
        //判断路径是否存在
        if(!file.exists()){
            file.mkdirs();
        }
        //绝对路径
        UUID uuid = UUID.randomUUID();
        File newfile = new File(filePath,uuid.toString()+"_"+fItem.getName());
        is = fItem.getInputStream();
        fos = new FileOutputStream(file);
        //传递输入输出流拷贝文件
        IOUtils.copy(is , fos);
     	stu.setImgUrl("Upload/"+uuid.toString()+"_"+fItem.getName());
     	
     	//根据Key(input标签的name属性值)获取value值
     	String value = map.get(fItem.getFieldName());
     	if(value== null){
      	    //代表第一次存储
     	    map.put(fItem.getFieldName(),fItem.getString());
     	}else{
     	    //不是第一次存储,复选框
                map.put(fItem.getFieldName(),value+","+fItem.getString());
     	}
     	
     	//把map中的数据存放到stu对象中,这里用到BeanUtils的jar包
        BeanUtils.populate(stu,map);
        
        //注意后面关流
        ....
    

    下载

    1. 前端页面
      • 下载链接传递到Servlet,并带上path=图片相对路径的属性
    2. Servlet
    //    获取前端传递的path属性
        String path = request.getParameter("path");
    //    截取出文件名
        String fileName = path.substring(path.lastIndexOf("/")+1);
    //    解决文件名的中文乱码问题
        fileName = URLEncoder.encode(fileName,"utf-8");
    //    获取图片完整路径
        path = getServletContext().getRealPath(path);
    //    设置响应头
        response.setHeader("Content-disposition","attachment;fileName="+fileName);
    //    创建输入输出流,用工具类复制
        fis = new FileInputStream(path); 
        os = response.getOutputStream();
        IOUtils.copy(fis,os);
    //    关流
        ....
    

    已经淘汰的内容,只是把多年前的学习笔记翻上来,不供参考

  • 相关阅读:
    服务器安全之修改3389远程桌面端口小工具(包源码)
    CYQ.Data.ProjectTool 项目配置工具发布(包源码)
    爱奇艺视频广告拦截失败,发文共商大计
    开发者基础知识游戏,共10关,欢迎挑战
    秋天新作品:秋式广告杀手,每年帮大伙多活78天!
    MySql Blob图片类型存储Bug解决:索引超出了数组界限错误
    爱奇艺视频广告拦截失败,发文共商大计
    简说宽带商的弹窗广告进化及网站应对之策(DNS劫持进化论)
    秋式广告杀手技术分享:网络请求基础知识
    通用社区登陆组件技术分享(开源)中篇:OAuth 登陆组件流程及组件集成方法
  • 原文地址:https://www.cnblogs.com/zohnn/p/13857454.html
Copyright © 2011-2022 走看看