EL&Filter&Listener:EL表达式和JSTL,Servlet规范中的过滤器,Servlet规范中的监听器,观察着设计模式,监听器的使用,综合案例学生管理系统

时间:2021-01-24 18:43:28   收藏:0   阅读:38

EL&Filter&Listener-授课

1 EL表达式和JSTL

1.1 EL表达式

1.1.1 EL表达式介绍 ***

技术分享图片

 

 

 

1.1.2 EL表达式的快速入门

  1. 创建一个 web 项目:el_demo,虚拟目录/el

  2. 在 web 目录下创建 el01.jsp

  3. 在文件中向域对象添加数据

  4. 使用三种方式获取域对象中的数据(java 代码块、JSP 表达式、EL 表达式)

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
       <title>EL表达式快速入门</title>
    </head>
    <body>
      <%--1.向域对象中添加数据--%>
      <% request.setAttribute("username","zhangsan"); %>
    ?
      <%--2.获取数据--%>
      Java代码块:<% out.println(request.getAttribute("username")); %> <br>
    ?
      JSP表达式:<%= request.getAttribute("username")%> <br>
    ?
      EL表达式:${username}
    </body>
    </html>
  5. 部署并启动项目

  6. 通过浏览器测试

    技术分享图片

     

     

1.1.3 EL表达式获取不同类型数据 ***

1.1.4 EL表达式的注意事项

1.1.5 EL表达式的运算符

 

1.1.6 EL表达式使用细节 ***

1.1.7 EL表达式的11个隐式对象

EL表达式也为我们提供隐式对象,可以让我们不声明直接来使用,十一个对象见下表,需要注意的是,它和JSP的隐式对象不是一回事:

EL中的隐式对象类型对应JSP隐式对象备注
PageContext *** Javax.serlvet.jsp.PageContext PageContext 完全一样
ApplicationScope Java.util.Map 没有 操作应用域对象数据
SessionScope Java.util.Map 没有 操作会话域对象数据
RequestScope Java.util.Map 没有 操作请求域对象数据
PageScope Java.util.Map 没有 操作页面域对象数据
Header Java.util.Map 没有 根据key获取请求消息头,值是一个
HeaderValues Java.util.Map 没有 根据key获取请求消息头,值是多个(数组)
Param Java.util.Map 没有 根据key获取请求参数,值是一个
ParamValues Java.util.Map 没有 根据key获取请求参数,值是多个(数组)
InitParam Java.util.Map 没有 根据key获取全局参数,value是参数值
Cookie Java.util.Map 没有 根据key获取cookie的值

1.2 JSTL

1.2.1 JSTL的介绍

技术分享图片

 

 

 

1.2.2 核心标签库

1)核心库介绍

在我们实际开发中,用到的jstl标签库主要以核心标签库为准,偶尔会用到国际化标签库的标签。下表中把我们经常可能用到的标签列在此处,其余标签库请同学们参考【JSTL标签库.doc】文档。

标签名称功能分类分类作用
<c:if> 流程控制 核心标签库 用于判断
<c:choose> ,<c:when>,<c:otherwise> 流程控制 核心标签库 用于多个条件判断
<c:foreache> 迭代操作 核心标签库 用于循环遍历

2)案例 ***

  1. 创建一个 web 项目:jstl_demo

  2. 在 web 目录下创建一个 WEB-INF 目录

  3. 在 WEB-INF 目录下创建一个 libs 目录,将 JSTL 的 jar 包导入

    • (jar包目录:day05_el表达式过滤器监听器\资料\JSTL的jar包)

    • 添加引用库

    技术分享图片

     

     

  4. 创建 JSP 文件,通过 taglib 导入 JSTL 标签库

  5. 对流程控制和迭代遍历的标签进行使用

    • 新建jstl01.jsp:流程控制

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <!--prefix给jstl core核心库起个前缀名,使用的标签就以c开头-->
      <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
      <html>
      <head>
         <title>流程控制</title>
      </head>
      <body>
        <%--向域对象中添加成绩数据--%>
        ${pageContext.setAttribute("score","T")}
      ?
        <%--对成绩进行判断--%>
         <c:if test="${score eq ‘A‘}">
            优秀
         </c:if>
      ?
        <%--对成绩进行多条件判断--%>
         <c:choose>
             <c:when test="${score eq ‘A‘}">优秀</c:when>
             <c:when test="${score eq ‘B‘}">良好</c:when>
             <c:when test="${score eq ‘C‘}">及格</c:when>
             <c:when test="${score eq ‘D‘}">较差</c:when>
             <c:otherwise>成绩非法</c:otherwise>
         </c:choose>
      </body>
      </html>
      ?
    • 新建jstl02.jsp:迭代遍历

      <%@ page import="java.util.ArrayList" %>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
      <html>
      <head>
         <title>循环</title>
      </head>
      <body>
        <%--向域对象中添加集合--%>
        <%
             ArrayList<String> list = new ArrayList<>();
             list.add("aa");
             list.add("bb");
             list.add("cc");
             list.add("dd");
             pageContext.setAttribute("list",list);
        %>
      ?
        <%--遍历集合--%>
         <c:forEach items="${list}" var="str">
            ${str} <br>
         </c:forEach>
      </body>
      </html>
      ?
  6. 部署并启动项目

  7. 通过浏览器查看

    • 访问jstl01

      技术分享图片

       

       

    • 访问jstl02

      技术分享图片

       

       

 

  1. 问题:项目运行报错

    技术分享图片

     

     

     

  2. 解决:

    技术分享图片

     

     

 

2 Servlet规范中的过滤器-Filter

2.1 过滤器入门

2.1.1 过滤器的介绍 ***

2.1.2 Filter介绍 ***

 

2.1.3 FilterChain ***

2.1.4 过滤器的使用 ***

 

 

2.1.5 Filter过滤器的使用细节

2.1.6 生命周期

2.1.7 FilterConfig过滤器配置对象

 

3 Servlet规范中的监听器-Listener

3.1 观察者设计模式 ***

3.2 监听对象的监听器

1) ServletContextListener ***

2) HttpSessionListener

3) ServletRequestListener

 

3.3 监听域对象属性变化的监听器

1) ServletContextAttributeListener

2) HttpSessionAttributeListener

3) ServletRequestAttributeListener

3.4 监听会话相关的感知性监听器

1) HttpSessionBindingListener

2) HttpSessionActivationListener

3.4 监听器的使用

技术分享图片

 

 

3.4.1 ServletContextListener的使用 ***

  1. 创建项目:listener_demo,虚拟路径/listener

  2. 创建com.itheima.listener.ServletContextListenerDemo

    package com.itheima.listener;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    /*
        ServletContext对象的创建和销毁的监听器
        //配置监听器:@WebListener
     */
    @WebListener
    public class ServletContextListenerDemo implements ServletContextListener{
        /*
            ServletContext对象创建的时候执行此方法
         */
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("监听到了对象的创建...");
    
            //获取对象
            ServletContext servletContext = sce.getServletContext();
            System.out.println(servletContext);
            
        }
    
        /*
            ServletContext对象销毁的时候执行此方法
         */
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("监听到了对象的销毁...");
        }
    }
  3. 启动项目:ServletContext是项目启动都会创建的,所以这里只需要启动tomcat

    技术分享图片

     

     

3.4.2 ServletContextAttributeListener的使用

  1. 新建ServletContextAttributeListenerDemo

    package com.itheima.listener;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextAttributeEvent;
    import javax.servlet.ServletContextAttributeListener;
    
    /*
        应用域对象中的属性变化的监听器
     */
    @WebListener
    public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener{
        /*
            向应用域对象中添加属性时执行此方法
         */
        @Override
        public void attributeAdded(ServletContextAttributeEvent scae) {
            System.out.println("监听到了属性的添加...");
    
            //获取应用域对象
            ServletContext servletContext = scae.getServletContext();
            //获取属性
            Object value = servletContext.getAttribute("username");
            System.out.println(value);
        }
    
        /*
            向应用域对象中替换属性时执行此方法
         */
        @Override
        public void attributeReplaced(ServletContextAttributeEvent scae) {
            System.out.println("监听到了属性的替换...");
    
            //获取应用域对象
            ServletContext servletContext = scae.getServletContext();
            //获取属性
            Object value = servletContext.getAttribute("username");
            System.out.println(value);
        }
    
        /*
            向应用域对象中移除属性时执行此方法
         */
        @Override
        public void attributeRemoved(ServletContextAttributeEvent scae) {
            System.out.println("监听到了属性的移除...");
    
            //获取应用域对象
            ServletContext servletContext = scae.getServletContext();
            //获取属性
            Object value = servletContext.getAttribute("username");
            System.out.println(value);
        }
    }
    
  2. 修改ServletContextListenerDemo:在contextInitialized中增加如下代码:

    //添加属性
    servletContext.setAttribute("username","zhangsan");
    
    //替换属性
    servletContext.setAttribute("username","lisi");
    
    //移除属性
    servletContext.removeAttribute("username");
  3. 启动tomcat

    技术分享图片

     

     

  4. 注解配置监听器,改为xml手动配置

    1. 注释两个demo中的//@WebListener

    2. web.xml增加如下配置

    <!--配置监听器-->
    <listener>
        <listener-class>com.itheima.listener.ServletContextListenerDemo</listener-class>
    </listener>
    
    <listener>
        <listener-class>com.itheima.listener.ServletContextAttributeListenerDemo</listener-class>
    </listener>

 

4 综合案例-学生管理系统改造 ***

4.1 需求说明

4.1.1 解决乱码问题

我们的学生管理系统中,肯定会有请求和响应的中文乱码问题。而乱码问题在学习Servlet的课程中已经讲解了如何解决了。只是在实际开发中,当有很多的Servlet时,肯定不能在每个Servlet中都编写一遍解决乱码的代码。因此,就可以利用我们今天学习的过滤器来实现统一解决请求和响应乱码的问题。

4.1.2 检查登录

在学生管理系统中,它包含了学生信息的录入和学生列表的查询,用户(员工)信息的录入以及查询。当然,我们实际的功能可能远远不止这些。但是就已有功能来说,也不是谁都可以通过地址栏直接输入访问的,它应该有权限的控制,只是我们课程在此处没法深入展开讲解权限,但最起码的登录,身份的认证还是必要的。

由此,就引出来一个问题,是在每次访问Servlet时,在Servlet的代码中加入是否认证过身份的判断吗?显然,是不合理的。那么,既然不是在每个Servlet中编写,就应该是统一管理和维护。此时,我们的过滤器就又可以出场了。

4.1.3 页面的java代码块和jsp表达式改造

我们今天除了学习了过滤器,还学习了EL表达式和JSTL标签库,它们的出现就是避免我们的JSP页面中有过多的java代码或者jsp表达式。我们要运用今天所学知识改造页面。

 

4.2 案例实现

4.2.1 过滤器解决全局乱码问题

  1. 代码

    package com.itheima.filter;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
        解决全局乱码问题
     */
    @WebFilter("/*")// /* 代表过滤所有的url
    public class EncodingFilter implements Filter{
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
            try{
                //1.将请求和响应对象转换为和HTTP协议相关
                HttpServletRequest request = (HttpServletRequest) servletRequest;
                HttpServletResponse response = (HttpServletResponse) servletResponse;
    
                //2.设置编码格式
                request.setCharacterEncoding("UTF-8");
                response.setContentType("text/html;charset=UTF-8");
    
                //3.放行
                filterChain.doFilter(request,response);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    

4.2.2 过滤解决检查登陆

  1. 代码

    package com.itheima.filter;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
        检查登录
     */
    @WebFilter(value = {"/addStudent.jsp","/listStudentServlet"})//过滤某些url通过value来指定
    public class LoginFilter implements Filter{
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
            try{
                //1.将请求和响应对象转换为和HTTP协议相关
                HttpServletRequest request = (HttpServletRequest) servletRequest;
                HttpServletResponse response = (HttpServletResponse) servletResponse;
    
                //2.获取会话域对象中数据
                Object username = request.getSession().getAttribute("username");
    
                //3.判断用户名
                if(username == null || "".equals(username)) {
                    //重定向到登录页面
                    response.sendRedirect(request.getContextPath() + "/login.jsp");
                    return;
                }
    
                //4.放行
                filterChain.doFilter(request,response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

4.2.3 EL表达式和JSTL优化JSP界面

  1. addStudent.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>添加学生</title>
    </head>
    <body>
    <%--注意:el表达式中如果想获取request对象,只能通过pageContext页面域获取
    		  pageContext.request,相当于java代码块里的pageContext.getRequest()
    --%>
    <form action="${pageContext.request.contextPath}/addStudentServlet" method="get" autocomplete="off">
        学生姓名:<input type="text" name="username"> <br>
        学生年龄:<input type="number" name="age"> <br>
        学生成绩:<input type="number" name="score"> <br>
        <button type="submit">保存</button>
    </form>
    </body>
    </html>
    
    • 重点:在jsp中通过EL表达式获取项目虚拟路径:${pageContext.request.contextPath}

  2. index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <html>
    <head>
        <title>学生管理系统首页</title>
    </head>
    <body>
        <%--
            获取会话域中的数据
            如果获取到了则显示添加和查看功能的超链接
            如果没获取到则显示登录功能的超链接
        --%>
        <c:if test="${sessionScope.username eq null}">
            <a href="${pageContext.request.contextPath}/login.jsp">请登录</a>
        </c:if>
    
        <c:if test="${sessionScope.username ne null}">
            <a href="${pageContext.request.contextPath}/addStudent.jsp">添加学生</a>
            <a href="${pageContext.request.contextPath}/listStudentServlet">查看学生</a>
        </c:if>
    
    </body>
    </html>
    
    • 注意:EL表达式会自动查找四大域对象中的共享数据,所以${sessionScope.username eq null}中的sessionScope可以省略,写成${username eq null}

  3. listStudent.jsp

    <%@ page import="com.itheima.bean.Student" %>
    <%@ page import="java.util.ArrayList" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <html>
    <head>
       <title>查看学生</title>
    </head>
    <body>
       <table width="600px" border="1px">
           <tr>
               <th>学生姓名</th>
               <th>学生年龄</th>
               <th>学生成绩</th>
           </tr>
    <%-- s是students遍历出来的每一个对象,EL表达式中可以使用此遍历 --%>      
           <c:forEach items="${students}" var="s">
               <tr align="center">
                   <td>${s.username}</td>
                   <td>${s.age}</td>
                   <td>${s.score}</td>
               </tr>
           </c:forEach>
       </table>
    </body>
    </html>
    ?
  4. login.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
       <title>学生登录</title>
    </head>
    <body>
       <form action="${pageContext.request.contextPath}/loginStudentServlet" method="get" autocomplete="off">
          姓名:<input type="text" name="username"> <br>
          密码:<input type="password" name="password"> <br>
           <button type="submit">登录</button>
       </form>
    </body>
    </html>

原文:https://www.cnblogs.com/859630097com/p/14320985.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!