09 Filter & Listener & Ajax

Filter

1、Filter概述

  • 简介
    在这里插入图片描述

    • 概念:Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一
    • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
    • 过滤器一般完成一些通用的操作,比如:权限控制、统一编码处理、敏感字符处理等等.
  • Filter快速入门

    • 开发步骤
      • 定义类,实现 Filter接口,并重写其所有方法
      • 配置Filter拦截资源的路径:在类上定义 @WebFilter 注解。而注解的 value 属性值 /* 表示拦截所有的资源
      • 在doFilter方法放行
    @WebFilter("/*")
    public class FilterDemo implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("1.FilterDemo...");
            //放行
            chain.doFilter(request,response);
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void destroy() {
        }
    }
    

2、Filter执行流程


Filter的执行流程如下:

3、Filter拦截路径配置

拦截路径有如下四种配置方式:

  • 拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截
  • 目录拦截:/user/*:访问/user下的所有资源,都会被拦截
  • 后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截
  • 拦截所有:/*:访问所有资源,都会被拦截

4、 过滤器链

  • 过滤器链是指在一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链。
    在这里插入图片描述
  • 使用注解配置的Filter的优先级是按照过滤器类名(字符串)的自然排序

5、案例

  1. 需求:访问服务器资源时,需要先进行登录验证,如果没有登录,则自动跳转到登录页面

    @WebFilter("/*")
    public class LoginFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
            HttpServletRequest req = (HttpServletRequest) request;
            
            //判断访问资源路径是否和登录注册相关
            //1,在数组中存储登陆和注册相关的资源路径
            String[] urls = {"/login.jsp","/imgs/","/css/","/loginServlet","/register.jsp","/registerServlet","/checkCodeServlet"};
            //2,获取当前访问的资源路径
            String url = req.getRequestURL().toString(); 
    
            //3,遍历数组,获取到每一个需要放行的资源路径
            for (String u : urls) {
                //4,判断当前访问的资源路径字符串是否包含要放行的的资源路径字符串
                /*
                    比如当前访问的资源路径是  /brand-demo/login.jsp
                    而字符串 /brand-demo/login.jsp 包含了  字符串 /login.jsp ,所以这个字符串就需要放行
                */
                if(url.contains(u)){
                    //找到了,放行
                    chain.doFilter(request, response);
                    //break;
                    return;
                }
            }
       
            //1. 判断session中是否有user
            HttpSession session = req.getSession();
            Object user = session.getAttribute("user");
    
            //2. 判断user是否为null
            if(user != null){
                // 登录过了
                //放行
                chain.doFilter(request, response);
            }else {
                // 没有登陆,存储提示信息,跳转到登录页面
    
                req.setAttribute("login_msg","您尚未登陆!");
                req.getRequestDispatcher("/login.jsp").forward(req,response);
            }
        }
    
        public void init(FilterConfig config) throws ServletException {
        }
    
        public void destroy() {
        }
    }
    

Listener

1、概述

  • Listener 表示监听器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。

  • 监听器就是当 applicationsessionrequest 三个对象创建、销毁或者往其中添加修改删除属性时会监听到,然后自动执行代码的功能组件

  • applicationServletContext 类型的对象

  • ServletContext 代表整个web应用,在服务器启动的时候,tomcat会自动创建该对象。在服务器关闭时会自动销毁该对象

2、分类

JavaWeb 提供了8个监听器:

ServletContextListener 接口中有以下两个方法

  • void contextInitialized(ServletContextEvent sce)ServletContext 对象被创建了会自动执行的方法
  • void contextDestroyed(ServletContextEvent sce)ServletContext 对象被销毁时会自动执行的方法

AJAX

1、概述

  • AJAX (Asynchronous JavaScript And XML):异步的 JavaScript 和 XML
  • 作用
    • 与服务器进行数据交换:通过AJAX可以给服务器发送请求,服务器将数据直接响应回给浏览器

      使用AJAX和服务器进行通信,以达到使用 HTML+AJAX来替换JSP页面
    • 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用校验,等等

2、快速入门

在这里插入图片描述

  1. 服务端实现
    在项目的创建 com.itheima.web.servlet ,并在该包下创建名为 AjaxServlet 的servlet

    @WebServlet("/ajaxServlet")
    public class AjaxServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1. 响应数据
            response.getWriter().write("hello ajax~");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    
  2. 客户端实现
    webapp 下创建名为 01-ajax-demo1.html 的页面,在该页面书写 ajax 代码

    • 创建核心对象,不同的浏览器创建的对象是不同的
     var xhttp;
    if (window.XMLHttpRequest) {
        xhttp = new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    • 发送请求
    //建立连接
    xhttp.open("GET", "http://localhost:8080/ajax-demo/ajaxServlet");
    //发送请求
    xhttp.send();
    
    • 获取响应
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            // 通过 this.responseText 可以获取到服务端响应的数据
            alert(this.responseText);
        }
    };
    

3、axios

  1. 简介

  2. 基本使用

    • (1)引入 axios 的 js 文件
      <script src="js/axios-0.18.0.js"></script>

    • (2)使用axios 发送请求,并获取响应结果

      //发送 get 请求
      axios({
          method:"get",
          url:"http://localhost:8080/ajax-demo1/aJAXDemo1?username=zhangsan"
      }).then(function (resp){
          alert(resp.data);
      })
      
      //发送 post 请求
      axios({
          method:"post",
          url:"http://localhost:8080/ajax-demo1/aJAXDemo1",
          data:"username=zhangsan"
      }).then(function (resp){
          alert(resp.data);
      });
      

      axios() 是用来发送异步请求的,小括号中使用 js 对象传递请求相关的参数:

      • method 属性:用来设置请求方式的。取值为 get 或者 post
      • url 属性:用来书写请求的资源路径。如果是 get 请求,需要将请求参数拼接到路径的后面,格式为: url?参数名=参数值&参数名2=参数值2
      • data 属性:作为请求体被发送的数据。也就是说如果是 post 请求的话,数据需要作为 data 属性的值。

      then() 需要传递一个匿名函数。我们将 then() 中传递的匿名函数称为 回调函数,意思是该匿名函数在发送请求时不会被调用,而是在成功响应后调用的函数。而该回调函数中的 resp 参数是对响应的数据进行封装的对象,通过 resp.data 可以获取到响应的数据。

  3. 请求方法别名
    为了方便起见, Axios 已经为所有支持的请求方法提供了别名。如下:

    • get 请求 : axios.get(url[,config])

    • delete 请求 : axios.delete(url[,config])

    • head 请求 : axios.head(url[,config])

    • options 请求 : axios.option(url[,config])

    • post 请求:axios.post(url[,data[,config])

    • put 请求:axios.put(url[,data[,config])

    • patch 请求:axios.patch(url[,data[,config])

    axios.get("http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan")
    	.then(function (resp) {
        alert(resp.data);
    });
    
    axios.post("http://localhost:8080/ajax-demo/axiosServlet","username=zhangsan")
    	.then(function (resp) {
        alert(resp.data);
    })
    

4、JSON

  1. 概述

    • JavaScript Object Notation:JavaScript 对象表示法

    • json 格式中的键要求必须使用双引号括起来, JavaScript没有强制要求

    • 作用:由于其语法格式简单,层次结构鲜明,现多用于作为数据载体,在网络中进行数据传输以前进行数据传递的方式(xml)

      <student>
          <name>张三</name>
          <age>23</age>
          <city>北京</city>
      </student>
      

      使用json

      {	
      	"name":"张三",
          "age":23,
          "city":"北京"
      }
      
  2. JSON 基础语法

    • 定义格式
      • JSON 本质就是一个字符串,但是该字符串内容是有一定的格式要求的。 定义格式如下:
        var 变量名 = '{"key":value,"key":value,...}';
      • JSON 串的键要求必须使用双引号括起来,而值根据要表示的类型确定
        • 数字(整数或浮点数)
        • 字符串(使用双引号括起来)
        • 逻辑值(true或者false)
        • 数组(在方括号中)
        • 对象(在花括号中)
        • null
      • 示例:var jsonStr = '{"name":"zhangsan","age":23,"addr":["北京","上海","西安"]}'
    • 获取属性值
      • json变量.属性名
      • parse(str) :将 JSON串转换为 js 对象
        var jsObject = JSON.parse(jsonStr); js对象.属性名
      • stringify(obj) :将 js 对象转换为 JSON 串
        var jsonStr = JSON.stringify(jsObject)
  3. 发送异步请求携带参数
    (1)使用 axios 发送请求时,可以提前定义一个 js 对象,用来封装需要提交的参数
    (2)只需要将需要提交的参数封装成 js 对象,并将该 js 对象作为 axiosdata 属性值进行,axios会自动将 js 对象转换为 JSON 串进行提交
    (3)发送异步请求时,如果请求参数是 JSON 格式,那请求方式必须是 POST。因为 JSON 串需要放在请求体中。

    var jsObject = {name:"张三"};
    
    axios({
        method:"post",
        url:"http://localhost:8080/ajax-demo/axiosServlet",
        data:jsObject  //这里 axios 会将该js对象转换为 json 串的
    }).then(function (resp) {
        alert(resp.data);
    })
    
  4. JSON串和Java对象的相互转换

    • json的作用:以 json 格式的数据进行前后端交互

      • 前端发送请求时,如果是复杂的数据就会以 json 提交给后端
      • 后端如果需要响应一些复杂的数据时,也需要以 json 格式将数据响应回给浏览器
        在这里插入图片描述
    • Fastjson 是阿里巴巴提供的一个Java语言编写的高性能功能完善的 JSON 库,是目前Java语言中最快的 JSON 库,可以实现 Java 对象和 JSON 字符串的相互转换

    • Fastjson 使用

      • 导入坐标
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        
      • Java对象转JSON
        String jsonStr = JSON.toJSONString(obj);
      • JSON字符串转Java对象
        User user = JSON.parseObject(jsonStr, User.class);

案例

  1. 使用Axios + JSON 完成品牌列表数据查询和添加

  2. 查询所有功能

    • 后端实现
      com.itheima.web 包下创建名为 SelectAllServletservlet,具体的逻辑如下:

      • 调用 service 的 selectAll() 方法进行查询所有的逻辑处理

      • 将查询到的集合数据转换为 json 数据。我们将此过程称为 序列化;如果是将 json 数据转换为 Java 对象,我们称之为 反序列化

      • 将 json 数据响应回给浏览器。这里一定要设置响应数据的类型及字符集 response.setContentType("text/json;charset=utf-8");

        SelectAllServlet 代码如下:

        @WebServlet("/selectAllServlet")
        public class SelectAllServlet extends HttpServlet {
            private BrandService brandService = new BrandService();
        
            @Override
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                //1. 调用Service查询
                List<Brand> brands = brandService.selectAll();
        
                //2. 将集合转换为JSON数据   序列化
                String jsonString = JSON.toJSONString(brands);
        
                //3. 响应数据  application/json   text/json
                response.setContentType("text/json;charset=utf-8");
                response.getWriter().write(jsonString);
            }
        
            @Override
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doGet(request, response);
            }
        }
        
    • 前端实现

      • 引入 js 文件
      • 绑定 页面加载完毕 事件
      • 发送异步请求
      • 处理响应数据
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      <a href="addBrand.html"><input type="button" value="新增"></a><br>
      <hr>
      <table id="brandTable" border="1" cellspacing="0" width="100%">
         
      </table>
      
      <script src="js/axios-0.18.0.js"></script>
      
      <script>
          //1. 当页面加载完成后,发送ajax请求
          window.onload = function () {
              //2. 发送ajax请求
              axios({
                  method:"get",
                  url:"http://localhost:8080/brand-demo/selectAllServlet"
              }).then(function (resp) {
                  //获取数据
                  let brands = resp.data;
                  let tableData = " <tr>\n" +
                      "        <th>序号</th>\n" +
                      "        <th>品牌名称</th>\n" +
                      "        <th>企业名称</th>\n" +
                      "        <th>排序</th>\n" +
                      "        <th>品牌介绍</th>\n" +
                      "        <th>状态</th>\n" +
                      "        <th>操作</th>\n" +
                      "    </tr>";
      
                  for (let i = 0; i < brands.length ; i++) {
                      let brand = brands[i];
      
                      tableData += "\n" +
                          "    <tr align=\"center\">\n" +
                          "        <td>"+(i+1)+"</td>\n" +
                          "        <td>"+brand.brandName+"</td>\n" +
                          "        <td>"+brand.companyName+"</td>\n" +
                          "        <td>"+brand.ordered+"</td>\n" +
                          "        <td>"+brand.description+"</td>\n" +
                          "        <td>"+brand.status+"</td>\n" +
                          "\n" +
                          "        <td><a href=\"#\">修改</a> <a href=\"#\">删除</a></td>\n" +
                          "    </tr>";
                  }
                  // 设置表格数据
                  document.getElementById("brandTable").innerHTML = tableData;
              })
          }
      </script>
      </body>
      </html>
      
  3. 添加品牌功能

    • 后端实现
      com.itheima.web 包下创建名为 AddServletservlet,具体的逻辑如下:

      • 获取请求参数

        由于前端提交的是 json 格式的数据,所以我们不能使用 request.getParameter() 方法获取请求参数

        • 如果提交的数据格式是 username=zhangsan&age=23 ,后端就可以使用 request.getParameter() 方法获取
        • 如果提交的数据格式是 json,后端就需要通过 request 对象获取输入流,再通过输入流读取数据
      • 将获取到的请求参数(json格式的数据)转换为 Brand 对象

      • 调用 service 的 add() 方法进行添加数据的逻辑处理

      • 将 json 数据响应回给浏览器

      AddServlet 代码如下:

      @WebServlet("/addServlet")
      public class AddServlet extends HttpServlet {
      
          private BrandService brandService = new BrandService();
      
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      
              //1. 接收数据,request.getParameter 不能接收json的数据
             /* String brandName = request.getParameter("brandName");
              System.out.println(brandName);*/
      
              // 获取请求体数据
              BufferedReader br = request.getReader();
              String params = br.readLine();
              // 将JSON字符串转为Java对象
              Brand brand = JSON.parseObject(params, Brand.class);
              //2. 调用service 添加
              brandService.add(brand);
              //3. 响应成功标识
              response.getWriter().write("success");
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      
    • 前端实现

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <title>添加品牌</title>
      </head>
      <body>
      <h3>添加品牌</h3>
      <form action="" method="post">
          品牌名称:<input id="brandName" name="brandName"><br>
          企业名称:<input id="companyName" name="companyName"><br>
          排序:<input id="ordered" name="ordered"><br>
          描述信息:<textarea rows="5" cols="20" id="description" name="description"></textarea><br>
          状态:
          <input type="radio" name="status" value="0">禁用
          <input type="radio" name="status" value="1">启用<br>
      
          <input type="button" id="btn"  value="提交">
      </form>
      
      <script src="js/axios-0.18.0.js"></script>
      
      <script>
          //1. 给按钮绑定单击事件
          document.getElementById("btn").onclick = function () {
              // 将表单数据转为json
              var formData = {
                  brandName:"",
                  companyName:"",
                  ordered:"",
                  description:"",
                  status:"",
              };
              // 获取表单数据
              let brandName = document.getElementById("brandName").value;
              // 设置数据
              formData.brandName = brandName;
      
              // 获取表单数据
              let companyName = document.getElementById("companyName").value;
              // 设置数据
              formData.companyName = companyName;
      
              // 获取表单数据
              let ordered = document.getElementById("ordered").value;
              // 设置数据
              formData.ordered = ordered;
      
              // 获取表单数据
              let description = document.getElementById("description").value;
              // 设置数据
              formData.description = description;
      
              let status = document.getElementsByName("status");
              for (let i = 0; i < status.length; i++) {
                  if(status[i].checked){
                      //
                      formData.status = status[i].value ;
                  }
              }
              //console.log(formData);
              //2. 发送ajax请求
              axios({
                  method:"post",
                  url:"http://localhost:8080/brand-demo/addServlet",
                  data:formData
              }).then(function (resp) {
                  // 判断响应数据是否为 success
                  if(resp.data == "success"){
                      location.href = "http://localhost:8080/brand-demo/brand.html";
                  }
              })
          }
      </script>
      </body>
      </html>
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值