1 EL 表达式
1.1 EL 表达式介绍
- EL(Expression Language):表达式语言
- 在 JSP 2.0 规范中加入的内容,也是 Servlet 规范的一部分
- 作用:在 JSP 页面中获取数据。让我们的 JSP 脱离 Java 代码块 和 JSP 表达式
- 语法:${表达式内容}
1.2 EL 表达式快速入门
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式快速入门</title>
</head>
<body>
<%-- 设置共享数据--%>
<% request.setAttribute("username","zhangsan"); %>
java 代码块:<%out.println("username");%><br/>
java 表达式:<%=request.getAttribute("username")%><br/>
EL 表达式:${username}
</body>
</html>
1.3 EL 表达式获取数据
<%@ page import="com.txt.bean.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式获取不同类型数据</title>
</head>
<body>
<%-- 1. 获取基本数据类型--%>
<% pageContext.setAttribute("num",10); %>
基本数据类型:${num}<br/>
<%-- 2. 获取自定义数据类型--%>
<%
Student stu = new Student("张三",23);
pageContext.setAttribute("stu",stu);
%>
自定义数据类型:${stu}<br/>
学生姓名:${stu.name}<br/>
学生年龄:${stu.age}
<%-- 3. 获取数组类型--%>
<%
String[] arr = {"hello","world"};
pageContext.setAttribute("arr",arr);
%>
数组:${arr}<br/>
0索引元素:${arr[0]}<br>
1索引元素:${arr[1]}<br>
<%-- 4. 获取List集合--%>
<%
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
pageContext.setAttribute("list",list);
%>
List集合:${list}<br/>
0索引元素:${list[0]}<br>
<%-- 5. 获取Map集合--%>
<%
HashMap<String,Student> map = new HashMap<>();
map.put("stu01",new Student("张三",23));
map.put("stu02",new Student("李四",24));
pageContext.setAttribute("map",map);
%>
Map集合:${map}<br>
第一个学生对象:${map.stu01}<br>
第一个学生对象的姓名:${map.stu01.name}<br>
</body>
</html>
1.4 EL 表达式注意事项
- EL 表达式没有空指针异常
- EL 表达式没有索引越界异常
- EL 表达式没有字符串的拼接异常
1.5 EL表达式运算符
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式运算符</title>
</head>
<body>
<%-- empty--%>
<%
String str1 = null;
String str2 = "";
int[] arr = {};
%>
${empty str1}<br>
${empty str2}<br>
${empty arr}<br>
<%-- 三元表达式--%>
<%
pageContext.setAttribute("gender","women");
%>
<input type="radio" name="gender" value="men" ${gender == "men" ? "checked":""} />男
<input type="radio" name="gender" value="women" ${gender == "women" ? "checked":""} />女
</body>
</html>
1.6 EL 表达式使用细节
- EL 表达式能够获取四大域对象的数据,根据从小到大在域对象中查找
- 还有可以获取 JSP 其他八个隐式对象,并调用其方法
- 代码演示
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL使用细节</title>
</head>
<body>
<%
request.setAttribute("username","张三");
%>
${username}<br>
<%--获取 JSP 其他八个隐式对象,并调用其方法--%>
${pageContext.request.contextPath}
</body>
</html>
1.7 EL 表达式隐式对象
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d7735c616d13a6c3a08dfd62aa32de05.png)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式11个隐式对象</title>
</head>
<body>
<%--pageContext对象 可以获取其他三个域对象和JSP中八个隐式对象--%>
${pageContext.request.contextPath} <br>
<%--applicationScope sessionScope requestScope pageScope 操作四大域对象中的数据--%>
<% request.setAttribute("username","zhangsan"); %>
${username} <br>
${requestScope.username} <br>
<%--header headerValues 获取请求头数据--%>
${header["connection"]} <br>
${headerValues["connection"][0]} <br>
<%--param paramValues 获取请求参数数据--%>
${param.username} <br>
${paramValues.hobby[0]} <br>
${paramValues.hobby[1]} <br>
<%--initParam 获取全局配置参数--%>
${initParam["pname"]} <br>
<%--cookie 获取cookie信息--%>
${cookie} <br> <%--获取Map集合--%>
${cookie.JSESSIONID} <br> <%--获取map集合中第二个元素--%>
${cookie.JSESSIONID.name} <br> <%--获取cookie对象的名称--%>
${cookie.JSESSIONID.value} <%--获取cookie对象的值--%>
</body>
</html>
2 JSTL
2.1 JSTL 介绍
- JSTL:JSP 标准标签库
- 主要提供给开发人员一个标准通用的标签库
- 开发人员可以利用这些标签取代 JSP 页面上的 Java代码,从而提高程序的可读性,降低程序的维护难度
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/893fc738c5ca5ca5741c6def62b513e3.png)
2.2 JSTL 核心标签库
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5315b0bb03d171fb4959151b1222c318.png)
2.3 JSTL基本使用
<%@ 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>
<%-- 向域对象中添加数据--%>
${pageContext.setAttribute("score","T")}
<%-- 对成绩进行判断--%>
<c:if test="${score eq 'A'}">
优秀
</c:if>
<%-- 对成绩进行多条件判断--%>
<c:choose>
<c:when test="${score == 'A'}">优秀</c:when>
<c:when test="${score == 'B'}">良好</c:when>
<c:when test="${score == 'C'}">及格</c:when>
<c:when test="${score == 'D'}">较差</c:when>
<c:otherwise>成绩非法</c:otherwise>
</c:choose>
</body>
</html>
<%@ 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>
3 Filter
3.1 过滤器介绍
- 过滤器——Filter,它是JavaWeb三大组件之一。另外两个是Servlet和Listener。
- 它是在2000年发布的Servlet2.3规范中加入的一个接口。是Servlet规范中非常实用的技术。
- 它可以对web应用中的所有资源进行拦截,并且在拦截之后进行一些特殊的操作。
- 常见应用场景:URL级别的权限控制;过滤敏感词汇;中文乱码问题等等。
- 过滤器一般用于完成通用操作,例如:登录验证、统一编码处理、敏感字符过滤等等…
3.2 Filter 介绍
- Filter 是一个借口。如果想实现过滤器的功能,必须实现该接口!
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/913f95c705c10f5caf958c8e0ef61e7f.png)
- 配置方式
注解方式
配置文件
3.3 FilterChain 介绍
- FilterChain 是一个接口,代表过滤器链对象,由 Servlet 容器提供实现类对象,直接使用即可
- 过滤器可以定义多个,就会组成过滤器链
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/289a325e110b2bf6ef15acf69f875b61.png)
如果有多个过滤器,在第一个过滤器中调用下一个过滤器,依次类推。直到到达最终访问资源
如果只有一个过滤器,放行时,就会直接到达最终访问资源
3.4 过滤器的使用
- 需求说明
通过 Filter 过滤器解决多个资源写出中文乱码的问题 - 最终目的
通过本需求,最终掌握 Filter 过滤器的作用 - 代码演示
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("ServletDemo01执行了...");
resp.getWriter().write("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("ServletDemo02执行了...");
resp.getWriter().write("ServletDemo02执行了...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
@WebFilter("/*")
public class FilterDemo01 implements Filter {
@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);
}
}
3.5 过滤器使用细节
- 配置方式
注解方式 @WebFilter(拦截路径)
配置文件方式
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b006e619efd830a80dcc8f81bd8840a8.png)
- 多个过滤器使用顺序
如果有多喝过滤器,取决于过滤器映射的顺序
3.6 过滤器生命周期
- 创建
当应用加载时实例化对象并执行 init 初始化方法 - 服务
对象提供服务的过程,执行 doFilter 方法 - 销毁
当应用卸载时或服务器停止时对象销毁,执行 destroy 方法
3.7 FilterConfig
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/262f92df00b4f0b5e8e33b4a104362b4.png)
- FilterConfig 是一个接口。可以加载一些初始化参数
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/afce73f6fb8f43e50efaefbbeafb5244.png)
- 代码演示
public class FilterDemo03 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("对象创建了...");
String filterName = filterConfig.getFilterName();
System.out.println(filterName);
String username = filterConfig.getInitParameter("username");
System.out.println(username);
}
@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() {
System.out.println("对象销毁了...");
}
}
<filter>
<filter-name>filterDemo03</filter-name>
<filter-class>com.txt.filter.FilterDemo03</filter-class>
<init-param>
<param-name>username</param-name>
<param-value>zhangsan</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filterDemo03</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.8 过滤器的五种拦截行为
- Filter 过滤器默认拦截的是请求,但在实际开发中,我们还有请求转发和请求包含,以及由服务器触发调用的全局错误页面,默认情况下过滤器是不参与过滤的,想要使用,就需要我们配置
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4feed0faf83a161037d305bfbed4cda4.png)
4 Listener
4.1 监听器介绍
- 观察者设计模式,所有监听器都是基于观察者设计模式的
- 三个组成部分
事件源:触发事件的对象
事件:触发的动作,封装了事件源
监听器:当事件源触发事件后,可以完成的功能 - 在程序当中,我们可以对:对象的创建销毁、域对象中属性的变化、会话相关内容进行监听
4.2 监听对象的监听器
- ServletContextListener:用于监听 ServletContext 对象的创建和销毁
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e58765982bedb807bbd8a6df038c0bf7.png)
- HttpSessionListener:用于监听 HttpSession 对象的创建和销毁
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/949e7dfecbbbac8ee54e52baeec92d60.png)
- ServletRequestListener:用于监听 ServletRequest 对象的创建和销毁
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f3be498688e1d1b0b42a988a0204c7b2.png)
4.3 监听域对象属性变化的监听器
- ServletContextAttributeListener:用于监听 ServletContext 应用域中属性的变化
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f76c495d6fb4f766494f435030c28fe0.png)
- HttpSessionAttributeListener:用于监听 HttpSession 会话域中属性的变化
- 核心方法
![](https://i-blog.csdnimg.cn/blog_migrate/3aa0344008388611df43bc88febe33fe.png)
- ServletRequestAttributeListener:用于监听 ServletRequest 请求域中属性的变化
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ab76cc8034a5961c9f647779c4ce9545.png)
4.4 监听会话相关的感知性监听器
- HttpSessionBindingListener:用于感知对象和会话域绑定的监听器
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f6be097cf0900113bb7221068a301190.png)
- HttpSessionActivationListener:用于感知会话域中对象钝化和活化的监听器
- 核心方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/32753e6b543d76429f8ed2c594e03cba.png)
4.5 监听器的使用
@WebListener
public class ServletContextListenerDemo implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象的创建...");
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听到了对象的销毁...");
}
}
- ServletContextAttributeListener 代码演示
@WebListener
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的添加...");
ServletContext servletContext = scae.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的移除...");
ServletContext servletContext = scae.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的修改...");
ServletContext servletContext = scae.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
}
@WebListener
public class ServletContextListenerDemo implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象的创建...");
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("username","zhangsan");
servletContext.setAttribute("username","lisi");
servletContext.removeAttribute("username");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听到了对象的销毁...");
}
}