一、EL表达式
1.1.特点
-
是一个由java开发的工具包
-
用于从特定域对象中读取并写入到响应体开发任务,不能向域对象中写入。
-
EL工具包自动存在Tomcat的lib中(el-api.jar),开发是可以直接使用,无需其他额外的包。
-
标准格式 : ${域对象别名.。关键字} 到指定的域中获取相应关键字的内容,并将其写入到响应体。
1.2.域对象
注:使用时可以省略域对象别名
默认查找顺序: pageScope -> requestScope -> sessionScope -> applicationScope
最好只在pageScope中省略
对应案例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsp</title>
</head>
<body>
<%
application.setAttribute("name","applcation");
session.setAttribute("name","session");
request.setAttribute("name","request");
pageContext.setAttribute("name","pageContext");
%>
<br>--------------使用java语言----------------<br>
application中的值:<%= application.getAttribute("name")%><br>
session中的值:<%= session.getAttribute("name")%><br>
request中的值:<%= request.getAttribute("name")%><br>
pageContext中的值:<%= pageContext.getAttribute("name")%><br>
<br>--------------使用EL表达式----------------<br>
application中的值:${applicationScope.name}<br>
session中的值:${sessionScope.name}<br>
request中的值:${requestScope.name}<br>
pageContext中的值:${pageScope.name}<br>
<br>--------------使用EL表达式,省略域对象----------------<br>
application中的值:${name}<br>
</body>
</html>
1.3.支持的运算
(1)数学运算
(2)比较运算 > gt < lt >= ge <= le == eq != !=
(3)逻辑预算 && || !
对应案例:
<%@ page import="com.sun.org.apache.xpath.internal.operations.Bool" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL运算</title>
</head>
<body>
<%
request.setAttribute("num1","12");
request.setAttribute("num2","14");
application.setAttribute("flag1",true);
application.setAttribute("flag2",false);
%>
<br>---------------使用java语言-------------------<br>
<%
String num1 = (String)request.getAttribute("num1");
String num2 = (String)request.getAttribute("num2");
int num3 = Integer.parseInt(num1)+Integer.parseInt(num2);
boolean flag1 = (Boolean)application.getAttribute("flag1");
boolean flag2 = (Boolean)application.getAttribute("flag2");
boolean flag3 = flag1 && flag2;
//输出方式一
out.write(Boolean.toString(flag3));
%>
<!-- 输出方式二 -->
<h1><%=num3%></h1>
<br>---------------使用EL表达式-------------------<br>
<h1>${ requestScope.num1 + requestScope.num2 }</h1>
<h1>${ requestScope.num1 > requestScope.num2 }</h1>
<h1>${ applicationScope.flag1 && applicationScope.flag2 }</h1>
</body>
</html>
1.4.其他的内置对象
(1)param 使用 ${param.请求参数名} 从请求参数中获取参数内容
(2)paramValues 使用 ${ paramValues.请求参数名 } 从请求参数中获取多个值,以数组的形式
(3)initParam 使用 ${ initParam.参数名 } 获取初始化参数
<%@ page import="com.sun.org.apache.xpath.internal.operations.Bool" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>其他内置对象</title>
</head>
<body>
url:...?username=zhangsan&password=admin<br>
url中的参数:用户名:${param.username} --- 密码:${param.password}<br>
-------------------------------------------<br>
url:...?username=zhangsan&username=lisi
url中的参数:用户1:${paramValues.username[0]} ---
用户2:${paramValues.username[1]}<br>
-------------------------------------------<br>
<!--
在web.xml中添加启动参数
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
-->
获取启动参数:${initParam.driver}
</body>
</html>
1.5.EL表达式的缺陷
(1)只能读取域对象中的值,不能写入
(2)不支持if判断和控制语句
二、 JSTL标签工具类
2.1.基本介绍
(1) JSP Standrad Tag Lib jsp标准标签库
(2) 是sun公司提供
(3) 组成
(4)使用原因:使用简单,且在JSP编程当中要求尽量不出现java代码。
2.2.使用方式
(1)导入依赖的jar包 jstl.jar standard.jar
(2)在jsp中引入JSTL的core包依赖约束
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2.3.重要标签的使用
2.3.1.<c: set>
在JSP文件上设置域对象中的共享数据
<%@ page import="com.sun.org.apache.xpath.internal.operations.Bool" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title> c:set </title>
</head>
<body>
<%--相当于
<%
request.setAttribute("name","zhangsan");
%>
--%>
<c:set scope="request" var="name" value="zhangsan"/>
通过JSTL添加的作用域的值:${requestScope.name} <br>
<c:set scope="application" var="name" value="lisi"/>
通过JSTL添加的作用域的值:${applicationScope.name} <br>
<c:set scope="session" var="name" value="wangwu"/>
通过JSTL添加的作用域的值:${sessionScope.name} <br>
<c:set scope="page" var="name" value="zhaoliu"/>
通过JSTL添加的作用域的值:${pageScope.name} <br>
</body>
</html>
2.3.2.<c: if>
控制哪些内容能够输出到响应体
<%@ page import="com.sun.org.apache.xpath.internal.operations.Bool" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title> c:if </title>
</head>
<c:set scope="page" var="age" value="20"/>
<br>---------------使用java语言------------------<br>
<%
if(Integer.parseInt((String)pageContext.getAttribute("age")) >= 18){
%>
输入:欢迎光临!
<% }else{ %>
输入:未满十八,禁止入内!
<% } %>
<br>---------------使用JSTL标签------------------<br>
<c:if test="${age ge 18}">
输入:欢迎光临!
</c:if>
<c:if test="${age lt 18}">
输入:未满十八,禁止入内!
</c:if>
</body>
</html>
2.3.3.<c: choose>
在jsp中进行多分支判断,决定哪个内容写入响应体
<%@ page import="com.sun.org.apache.xpath.internal.operations.Bool" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title> c:choose </title>
</head>
<body>
<c:set scope="page" var="age" value="20"/>
<br>---------------使用java语言------------------<br>
<%
if(Integer.parseInt((String)pageContext.getAttribute("age")) == 18){
%>
输出:您今年成年了
<% }else if(Integer.parseInt((String)pageContext.getAttribute("age")) > 18){ %>
输出:您已经成年了
<% }else{ %>
输出:您还是个孩子
<% } %>
<br>---------------使用JSTL标签------------------<br>
<c:choose>
<c:when test="${age eq 18}">
输出:您今年成年了
</c:when>
<c:when test="${age gt 18}">
输出:您已经成年了
</c:when>
<c:otherwise>
输出:您还是个孩子
</c:otherwise>
</c:choose>
</body>
</html>
2.3.4.<c: forEach>
循环遍历
<c:forEach var="申明循环变量的名称" begin="初始化循环变量"
end="循环变量可以接受的最大值" step="循环变量的递增或递减值">
*** step属性可以不写,默认递增1
*** 循环变量默认保存在pageContext中
</c:forEach>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="dao.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title> c:forEach </title>
</head>
<body>
<%
pageContext.setAttribute("students",new ArrayList(){{
add(new Student("01","zhangsan",16));
add(new Student("02","lisi",19));
add(new Student("03","wangwu",15));
}});
pageContext.setAttribute("stuMap",new HashMap(){{
put("s1",new Student("01","zhangsan",16));
put("s2",new Student("02","zhangsan",19));
put("s3",new Student("03","zhangsan",15));
}});
%>
<br>---------------使用java语言----------------<br>
<table>
<tr><td>学号</td><td>姓名</td><td>年龄</td></tr>
<%
List<Student> students = (ArrayList<Student>)pageContext.getAttribute("students");
for (int i = 0; i < students.size(); i++) {
%>
<tr>
<td><%=students.get(i).getSid()%></td>
<td><%=students.get(i).getName()%></td>
<td><%=students.get(i).getAge()%></td>
</tr>
<% } %>
</table>
<br>---------------使用JSTL标签读取list----------------<br>
<table>
<tr><td>学号</td><td>姓名</td><td>年龄</td></tr>
<c:forEach var="stu" items="${students}">
<tr>
<td>${stu.sid}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
</tr>
</c:forEach>
</table>
<br>---------------使用JSTL标签读取Map----------------<br>
<table>
<tr><td>key值</td><td>学号</td><td>姓名</td><td>年龄</td></tr>
<c:forEach var="stu" items="${stuMap}">
<tr>
<td>${stu.key}</td>
<td>${stu.value.sid}</td>
<td>${stu.value.name}</td>
<td>${stu.value.age}</td>
</tr>
</c:forEach>
</table>
<br>---------------使用JSTL标签读取指定for循环----------------<br>
<c:forEach var="item" begin="1" end="10" step="1">
<option> ${item} </option>
</c:forEach>
</body>
</html>
其中使用的javaBean
public class Student {
private String sid;
private String name;
private int age;
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String sid, String name, int age) {
this.sid = sid;
this.name = name;
this.age = age;
}
}
三、Listener、Filter
3.1.概念
-
servlet
servlet是一种运行服务器端的java应用程序,他可以用来处理请求和响应。
-
filter
过滤器,不像servlet,它不能产生一个请求或者响应,它是一个中间者,能修改处理经过它的请求和响应,并不能直接给客户端响应。
-
listener
监听器,它用来监听容器内的一些变化,如session的创建,销毁等。当变化产生时,监听器就要完成一些工作。
3.2.生命周期
1、servlet: servlet的生命周期始于它被装入web服务器的内存时,并在web服务器终止或重新装入servlet时结束。servlet一旦被装入web服务器,一般不会从web服务器内存中删除,直至web服务器关闭或重新开始。
1.装入:启动服务器时加载Servlet的实例;
2.初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作由init()方法负责执行完成;
3.调用:从第一次到以后的多次访问,都是只调用doGet()或doPost()方法;
4.销毁:停止服务器时调用destory()方法,销毁实例。
2、filter: 一定要实现javax.servlet包的Filter接口的三个方法init()、doFilter()、destory(),空实现也行
1.启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
2.每一次请求时都只调用方法doFilter()进行处理;
3.停止服务器时调用destory()方法,销毁实例。
3、listener: 类似于servlet和filter
servlet2.4规范中提供了8个listener接口,可以将其分为三类,分别如下:
-
第一类:与servletContext有关的listener接口。包括:ServletContextListener、ServletContextAttributeListener;
-
第二类:与HttpSession有关的Listener接口。包括:HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener、HttpSessionActivationListener;
-
第三类:与ServletRequest有关的Listener接口,包括:ServletRequestListener、ServletRequestAttributeListener
web.xml 的加载顺序是:context- param -> listener -> filter -> servlet
3.3.使用方式
listener:
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class TestListener implements HttpSessionListener, ServletRequestListener, ServletRequestAttributeListener {
//sessionListener start!
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
logger.info("............TestListener sessionCreated().............");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
logger.info("............TestListener sessionDestroyed().............");
}
//sessionListener end!
//requestListener start!
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
logger.info("............TestListener requestInitialized().............");
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
logger.info("............TestListener requestDestroyed().............");
}
//requestListener end!
//attributeListener start!
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
logger.info("............TestListener attributeAdded().............");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
logger.info("............TestListener attributeRemoved().............");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
logger.info("............TestListener attributeReplaced().............");
}
//attributeListener end!
}
Filter:
import javax.servlet.*;
import java.io.IOException;
public class TestFilter 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("过滤器被执行了");
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
Servlet:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TestServlet extends HttpServlet {
@Override
public void init() throws ServletException {
super.init();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
//...TestdoPost doPost() start...
//操作Attribute
req.setAttribute("a","a");
req.setAttribute("a","b");
req.getAttribute("a");
req.removeAttribute("a");
//操作session
req.getSession().setAttribute("a","a");
req.getSession().getAttribute("a");
req.getSession().invalidate();
//...TestdoPost doPost() end...
}
@Override
public void destroy() {
super.destroy();
}
}
配置XML
<!-- 测试filter -->
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>test.TestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<!-- 测试servlet -->
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>test.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- 测试listener -->
<listener>
<listener-class>test.TestListener</listener-class>
</listener>