EL、JSTL、过滤器和监听器

EL表达式

EL快速入门

使用EL表达式能够简化JSP页面中Java代码的编写。格式非常简单,只需要在JSP页面中嵌入${表达式}即可。

 <%--将用户名存入请求域--%>
<%request.setAttribute("username","zhangsan");%>    <br>

Java代码获取数据:<%out.println(request.getAttribute("username"));%><br>

JSP表达式:<%=request.getAttribute("username")%><br>

EL获取数据:${username}

EL获取域值

EL表达式根据域对象中存储的数据类型不同,获取方式也稍有不同。

EL获取基本类型数据

<!--在request域中存数据-->
<% request.setAttribute("num",10); %>
    
<!--获取num的值-->
${num}  <br>

EL获取自定义对象

<!--request域中存储Student对象-->
<%
Student stu=new Student("张三",20);
request.setAttribute("stu",stu);
%>

<!--EL获取Student对象的属性值-->
学生对象:${stu}  <br>
学生姓名:${stu.name}  <br>
学生年龄:${stu.age}  <br>

EL获取List集合

<!--request域中存储List集合-->
<%
ArrayList<Student> list=new ArrayList<>();
list.add(new Student("张三",20));
list.add(new Student("李四",30));
request.setAttribute("list",list);
%>

<!--EL获取request域中的list集合,以及其元素-->
获取list集合:${list}  <br>
获取list集合的0索引学生:${list[0]}<br>
获取list集合的1索引学生姓名:${list[1].name}<br>

EL获取Map集合

<!--request域中存储Map集合-->
<%
Map<String,String> map=new HashMap<>();
map.put("孙悟空","花果山");
map.put("猪八戒","高老庄");
map.put("沙和尚","流沙河");
request.setAttribute("map",map);
%>

<!--EL获取request域中的map集合,以及其元素-->
获取map集合:${map}  <br>
获取map集合中键对应的值:${map["孙悟空"]}  <br>

EL运算符

算数运算符:+ - * / %
比较运算符:== != > >= < <=
逻辑运算符:&& || !
空运算符:empty
    功能:用于判断集合、数组、字符串是否为null并且长度是否为0
    ${empty list}

根据域中存储的数据,让单选框选中男或女

<%request.setAttribute("gender","女");%>
<input type="radio" value="男" ${gender=="男"?"checked":""}> 男
<input type="radio" value="女"${gender=="女"?"checked":""}> 女

EL表达式细节

1.EL表达式可以获取四大域的数据,依次从小到大的域中查找指定键名对应的值,如果找到了就不再往下找.
2.EL表达式可以获取八大隐式对象

JSTL标签库

JSTL(全称JavaServer Pages Tag Library)意为JSP标准标签库,可以用来简化在JSP页面中Java代码的编写。

在JSP页面导入JSTL包

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

常用JSTL标签

<!--if标签:相当于Java的if语句-->
<c:if test="${number%2==0}"> 
    ${number}是偶数
</c:if>

<!--choose标签:相当于Java的switch语句-->
<c:choose>
    <c:when test="${number==1}">星期一</c:when>
    <c:when test="${number==2}">星期二</c:when>
    <c:when test="${number==3}">星期三</c:when>
</c:choose>

<!--foreach标签:相当于Java的for循环-->
<c:forEach begin="0" end="${list.size()}" step="1" var="i">
    <c:if test="${list[i]!=null}">
        ${list[i].name},${list[i].age}<br>
    </c:if>
</c:forEach>

<!--foreach标签:类似Java增强for循环-->
<c:forEach items="${list}" var="element">
    ${element.name},${element.age}<br>
</c:forEach>

过滤器Filter

当客户端访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。举个例子帮助大家理解,比如2020年初在爆发了新冠病毒疫情,为了防止病毒扩算到全国,武汉市宣布封城,所有交通渠道限制通行,在各个出入口设卡拦截,只有体温正常的医务人员和急救物资才能进入城区。这里武汉市各个出入口的关卡,起到的就是过滤器的作用。

在程序中是同样的道理,比如用户在访问服务器资源时只允许登录过的用户才能正常访问。这里登录校验起到的就是过滤器的作用。除了登录校验,在程序中过滤器的用处还有统一编码处理,铭感词汇过滤等等。

过滤器统一编码

@WebFilter("/*")
public class FilterDemo1 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("FilterDemo1过滤器执行了");
        servletResponse.setContentType("text/html;charset=utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

过滤器拦截配置

1. 具体资源路径: /index.jsp 
    只有访问index.jsp资源时,过滤器才会被执行
2. 拦截目录: /user/*    
    访问/user下的所有资源时,过滤器都会被执行
3. 后缀名拦截: *.jsp        
    访问所有后缀名为jsp资源时,过滤器都会被执行
4. 拦截所有资源:/*        
    访问所有资源时,过滤器都会被执行

过滤器的生命周期

1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
2. doFilter:每一次请求被拦截资源时,会执行。执行多次
3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源

配置方式

方式一:注解方式: @WebFilter("拦截路径")

方式二:XML配置,如下:

多个过滤器使用顺序

如果有多个过滤器,取决于过滤器映射的顺序,也就是<filter-mapping>的配置顺序。

如果是注解的方式配置Filter,那么Filter的执行顺序和类名有关,但是不靠谱,建议使用xml方式配置Filter,使用<filter-mapping>配置执行顺序。

核心方法

代码演示

配置初始化参数

<filter>
  <filter-name>filterDemo04</filter-name>
  <filter-class>com.itheima.filter.FilterDemo04</filter-class>
  <init-param>
    <param-name>username</param-name>
    <param-value>zhangsan</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>filterDemo04</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

获取初始化参数

//@WebFilter("/*")
public class FilterDemo04 implements Filter{

  /*
        初始化方法
     */
  @Override
  public void init(FilterConfig filterConfig) {
    System.out.println("对象初始化成功了...");

    //获取过滤器名称
    String filterName = filterConfig.getFilterName();
    System.out.println(filterName);

    //根据name获取value
    String username = filterConfig.getInitParameter("username");
    System.out.println(username);
  }
  //其他方法省略不写了...
}

过滤器五种拦截行为【补充】

问题:如何使过滤器拦截转发的请求和响应?

介绍

Filter 过滤器默认拦截的是客户端发送过来的请求,但是在实际开发中,我们还有请求转发,以及由服务器触发调用的全局错误页面。默认情况下过滤器是不参与过滤的,要想使用,就需要我们配置。

拦截方式

<filter>
  <filter-name>filterDemo05</filter-name>
  <filter-class>com.itheima.filter.FilterDemo05</filter-class>
  <!--配置开启异步支持,当dispatcher配置ASYNC时,需要配置此行-->
  <async-supported>true</async-supported>
</filter>
<filter-mapping>
  <filter-name>filterDemo05</filter-name>
  <!--<url-pattern>/error.jsp</url-pattern>-->
  <url-pattern>/*</url-pattern>
  <!--过滤客户端发送的请求:默认值。-->
  <dispatcher>REQUEST</dispatcher>
   <!--过滤请求转发:当请求转发时,过滤器工作。-->
  <dispatcher>FORWARD</dispatcher>
  
  <!--过滤全局错误页面:当由服务器调用全局错误页面时,过滤器工作-->
  <dispatcher>ERROR</dispatcher>
  <!--过滤请求包含:当请求包含时,过滤器工作。它只能过滤动态包含,jsp的include指令是静态包含,过滤器不会起作用-->
  <dispatcher>INCLUDE</dispatcher>
  <!--过滤异步类型,它要求我们在filter标签中配置开启异步支持-->
  <dispatcher>ASYNC</dispatcher>
</filter-mapping>

核心:知道REQUEST和FORWARD就行了,REQUEST表示拦截客户端浏览器发送的请求,FORWARD拦截转发的请求。

如果是使用注解配置过滤器,那么拦截方式设置如下:@WebFilter(value = {"/servletDemo01","/servletDemo02"},dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST})

监听器Listener

监听器用于监听web应用中某些对象的创建和销毁,属性的增加、修改和删除等事件。当事件发生时,作出相应的响应处理。常用于统计在线人数,系统加载时进行信息初始化,统计网站的访问量等等。

对象监听器

ServletContextListener
    监听应用的创建和销毁
ServletRequestListener
    监听请求的创建和销毁
HttpSessionListener
    监听Session的创建和销毁

属性监听器

ServletContextAttributeListener
    监听应用域属性的添加,修改和删除
ServletRequestAttributeListener
    监听请求域属性的添加,修改和删除
HttpSessionAttributeListener
    监听Session域属性的添加,修改和删除

统计访问人数

定义Session对象监听器,只有一个用户访问就会为该用户创建一个HttpSeesion对象。当用户关闭浏览器时

@WebListener
public class ListenerDemo1 implements HttpSessionListener {
    private int number=0;
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        number++;
        se.getSession().setAttribute("number",number);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        number--;
        se.getSession().setAttribute("number",number);
    }
}

总结

1 EL表达式
	作用:简化jsp页面java代码的书写,用来从域对象中获取数据。
	语法:${表达式}
	EL表达式获取不同类型数据:
	request.setAttribute("num",10); ------> ${num}
	
	request.setAttribute("stu",student); ------> ${stu.name}    ${stu.name}
	
	request.setAttribute("students",list); --> ${students[1].name}  ${students[1].name}
	
	EL中使用运算符:
		${empty stu?"":stu.name}   
		${not empty stu?stu.name:""} 
	EL获取虚拟目录:
		${pageContext.request.contextPath}
		
2 JSTL标签库
【第一步】添加jstl对应的jar包
【第二步】在jsp页面使用taglib引入核心标签库
	<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
【第三步】使用标签库中的标签
	<c:if test="${}">
	
	</c:if>
	<c:choose>
		<c:when test=${}></c:when>
		<c:when test=${}></c:when>
		... ...
		<c:otherwise></c:otherwise>
	</c:choose>
	
	<c:forEach var="i" begin="0" end="${list.size()-1}" step="1">
		
	</c:forEach>
	
	<c:forEach items="${list}" var="stu" varStatus="statu">
		
	</c:forEach>
	
3 Filter过滤器【重要】
	作用:拦截请求和响应,拦截到之后我们可以放行也可以不放行。
	定义一个filter过滤器:在包上鼠标右键--->web filter【重要】
	@WebFilter("/*")
	public class FilterDemo01 implements Filter{
	    public void init(FilterConfig config) throws ServletException {}
    	public void destroy() {}
    	@Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
			
			//放行
			chain.doFilter(request,response);
        }
	}
	使用细节:
		1 如果有多个过滤器,过滤器的执行顺序由filter-mapping的先后位置绝对。
		2 服务器启动的时候就会创建Filter过滤器
		3 如果要拦截转发的请求,需要设置dispatcher。
		   xml配置:
			 <!--过滤客户端发送的请求:默认值。-->
              <dispatcher>REQUEST</dispatcher>
               <!--过滤请求转发:当请求转发时,过滤器工作。-->
              <dispatcher>FORWARD</dispatcher>
            注解配置: 
              dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST}
	
4 Listener监听器
	作用:监听域对象的创建/销毁,监听域对象中值的变化(添加值,替换值,移除值),监听session中存储对象的变化(绑定/解绑,钝化/活化)
	
	@WebListener
	public class ContextLoaderListener implements ServletContextListener{
		//重写监听器中的所有抽象方法
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值