EL&Filter&Listener
1.EL表达式概述
基本概念
EL表达式,全称是Expression Language。意为表达式语言。它是Servlet规范中的一部分,是JSP2.0规范加入的内容。其作用是用于在JSP页面中获取数据,从而让我们的JSP脱离java代码块和JSP表达式。
基本语法
EL表达式的语法格式非常简单,写为 ${表达式内容}
例如:在浏览器中输出请求域中名称为message的内容。
假定,我们在请求域中存入了一个名称为message的数据(request.setAttribute("message","EL");
),此时在jsp中获取的方式,如:${message}
。
1)获取四大域中的数据
它只能从四大域中获取数据,调用的就是findAttribute(name,value);
方法,根据名称由小到大逐个域中查找,找到就返回,找不到就什么都不显示。
它可以获取对象,可以是对象中关联其他对象,可以是一个List集合,也可以是一个Map集合。
2)EL表达式的注意事项
在使用EL表达式时,它帮我们做了一些处理,使我们在使用时可以避免一些错误。它没有空指针异常,没有数组下标越界,没有字符串拼接。
3)EL表达式的使用细节
EL表达式除了能在四大域中获取数据,同时它可以访问其他隐式对象,并且访问对象有返回值的方法.
4)EL表达式的运算符
EL表达式中运算符如下图所示,它们都是一目了然的:
2. EL表达式的11个隐式对象
1)隐式对象介绍
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,值是value(一个) |
HeaderValues | Java.util.Map | 没有 | 请求消息头key,值是数组(一个头多个值) |
Param | Java.util.Map | 没有 | 请求参数key,值是value(一个) |
ParamValues | Java.util.Map | 没有 | 请求参数key,值是数组(一个名称多个值) |
InitParam | Java.util.Map | 没有 | 全局参数,key是参数名称,value是参数值 |
Cookie | Java.util.Map | 没有 | Key是cookie的名称,value是cookie对象 |
3.Servlet规范中的过滤器-Filter
1)过滤器概念及作用
过滤器——Filter,它是JavaWeb三大组件之一。另外两个是Servlet和Listener。它是在2000年发布的Servlet2.3规范中加入的一个接口。是Servlet规范中非常实用的技术。它可以对web应用中的所有资源进行拦截,并且在拦截之后进行一些特殊的操作。
常见的应用场景:URL级别的权限控制;过滤敏感词汇;中文乱码问题等等。
2)过滤器使用
@WebFilter("/*")//拦截所有路径,"/servletDemo01" 拦截servletDemo01路径
public class FilterDemo01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterDemo01执行了...");
//处理乱码
servletResponse.setContentType("text/html;charset=UTF-8");
//放行
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("ServletDemo01执行了...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
@WebServlet("/servletDemo02")
public class ServletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("ServletDemo01执行了...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.Servlet规范中的监听器-Listener
1)观察者设计模式
在介绍监听器之前,先跟同学们普及一个知识,观察者设计模式。因为所有的监听器都是观察者设计模式的体现。
那什么是观察者设计模式呢?
它是事件驱动的一种体现形式。就好比在做什么事情的时候被人盯着。当对应做到某件事时,触发事件。
观察者模式通常由以下三部分组成:
事件源:触发事件的对象。
事件:触发的动作,里面封装了事件源。
监听器:当事件源触发事件时,要做的事情。一般是一个接口,由使用者来实现。
5. Servlet规范中的8个监听器简介
1.监听对象创建的
1)ServletContextListener
/**
* 用于监听ServletContext对象创建和销毁的监听器
* @since v 2.3
*/
public interface ServletContextListener extends EventListener {
/**
* 对象创建时执行此方法。该方法的参数是ServletContextEvent事件对象,事件是【创建对象】这个动作
* 事件对象中封装着触发事件的来源,即事件源,就是ServletContext
*/
public default void contextInitialized(ServletContextEvent sce) {
}
/**
* 对象销毁执行此方法
*/
public default void contextDestroyed(ServletContextEvent sce) {
}
}
2)HttpSessionListener
/**
* 用于监听HttpSession对象创建和销毁的监听器
* @since v 2.3
*/
public interface HttpSessionListener extends EventListener {
/**
* 对象创建时执行此方法。
*/
public default void sessionCreated(HttpSessionEvent se) {
}
/**
* 对象销毁执行此方法
*/
public default void sessionDestroyed(HttpSessionEvent se) {
}
}
3)ServletRequestListener
/**
* 用于监听ServletRequest对象创建和销毁的监听器
* @since Servlet 2.4
*/
public interface ServletRequestListener extends EventListener {
/**
* 对象创建时执行此方法。
*/
public default void requestInitialized (ServletRequestEvent sre) {
}
/**
* 对象销毁执行此方法
*/
public default void requestDestroyed (ServletRequestEvent sre) {
}
}
2.监听域中属性发生变化的
1)ServletContextAttributeListener
/**
* 用于监听ServletContext域(应用域)中属性发生变化的监听器
* @since v 2.3
*/
public interface ServletContextAttributeListener extends EventListener {
/**
* 域中添加了属性触发此方法。参数是ServletContextAttributeEvent事件对象,事件是【添加属性】。
* 事件对象中封装着事件源,即ServletContext。
* 当ServletContext执行setAttribute方法时,此方法可以知道,并执行。
*/
public default void attributeAdded(ServletContextAttributeEvent scae) {
}
/**
* 域中删除了属性触发此方法
*/
public default void attributeRemoved(ServletContextAttributeEvent scae) {
}
/**
* 域中属性发生改变触发此方法
*/
public default void attributeReplaced(ServletContextAttributeEvent scae) {
}
}
2)HttpSessionAttributeListener
/**
* 用于监听HttpSession域(会话域)中属性发生变化的监听器
* @since v 2.3
*/
public interface HttpSessionAttributeListener extends EventListener {
/**
* 域中添加了属性触发此方法。
*/
public default void attributeAdded(HttpSessionBindingEvent se) {
}
/**
* 域中删除了属性触发此方法
*/
public default void attributeRemoved(HttpSessionBindingEvent se) {
}
/**
* 域中属性发生改变触发此方法
*/
public default void attributeReplaced(HttpSessionBindingEvent se) {
}
}
3)ServletRequestAttributeListener
/**
* 用于监听ServletRequest域(请求域)中属性发生变化的监听器
* @since Servlet 2.4
*/
public interface ServletRequestAttributeListener extends EventListener {
/**
* 域中添加了属性触发此方法。
*/
public default void attributeAdded(ServletRequestAttributeEvent srae) {
}
/**
* 域中删除了属性触发此方法
*/
public default void attributeRemoved(ServletRequestAttributeEvent srae) {
}
/**
* 域中属性发生改变触发此方法
*/
public default void attributeReplaced(ServletRequestAttributeEvent srae) {
}
}
3.和会话相关的两个感知型监听器
和会话域相关的两个感知型监听器是无需配置的,直接编写代码即可。
1)HttpSessionBinderListener
/**
* 用于感知对象和和会话域绑定的监听器
* 当有数据加入会话域或从会话域中移除,此监听器的两个方法会执行。
* 加入会话域即和会话域绑定
* 从会话域移除即从会话域解绑
*/
public interface HttpSessionBindingListener extends EventListener {
/**
* 当数据加入会话域时,也就是绑定,此方法执行
*/
public default void valueBound(HttpSessionBindingEvent event) {
}
/**
* 当从会话域移除时,也就是解绑,此方法执行
*/
public default void valueUnbound(HttpSessionBindingEvent event) {
}
}
2)HttpSessionActivationListener
/**
* 用于感知会话域中对象钝化和活化的监听器
*/
public interface HttpSessionActivationListener extends EventListener {
/**
* 当会话域中的数据钝化时,此方法执行
*/
public default void sessionWillPassivate(HttpSessionEvent se) {
}
/**
* 当会话域中的数据活化时(激活),此方法执行
*/
public default void sessionDidActivate(HttpSessionEvent se) {
}
}
4.监听器的使用
1)ServletContextListener的使用
@WebListener
public class ServletContextListenerDemo implements ServletContextListener {
/**
* 对象创建时,执行此方法
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象的创建");
//1.获取事件源对象
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
}
/**
* 对象销毁时,执行此方法
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听到了对象的销毁");
}
}
2)ServletContextAttributeListener
@@WebListener
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener {
/**
* 域中添加了数据
*/
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("监听到域中加入了属性");
/**
* 由于除了我们往域中添加了数据外,应用在加载时还会自动往域中添加一些属性。
* 我们可以获取域中所有名称的枚举,从而看到域中都有哪些属性
*/
//1.获取事件源对象ServletContext
ServletContext servletContext = scae.getServletContext();
//2.获取域中所有名称的枚举
Enumeration<String> names = servletContext.getAttributeNames();
//3.遍历名称的枚举
while(names.hasMoreElements()){
//4.获取每个名称
String name = names.nextElement();
//5.获取值
Object value = servletContext.getAttribute(name);
//6.输出名称和值
System.out.println("name is "+name+" and value is "+value);
}
}
/**
* 域中移除了数据
*/
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("监听到域中移除了属性");
}
/**
* 域中属性发生了替换
* @param scae
*/
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("监听到域中属性发生了替换");
}
}
同时,我们还需要借助第一个ServletContextListenerDemo
监听器,往域中存入数据,替换域中的数据以及从域中移除数据,代码如下:
@WebListener
public class ServletContextListenerDemo implements ServletContextListener {
/**
* 对象创建时,执行此方法
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象的创建");
//1.获取事件源对象
ServletContext servletContext = sce.getServletContext();
//2.往域中加入属性
servletContext.setAttribute("servletContext","test");
}
/**
* 对象销毁时,执行此方法
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
//1.取出事件源对象
ServletContext servletContext = sce.getServletContext();
//2.往域中加入属性,但是名称仍采用servletContext,此时就是替换
servletContext.setAttribute("servletContext","demo");
System.out.println("监听到了对象的销毁");
//3.移除属性
servletContext.removeAttribute("servletContext");
}
}