一、Servlet的生命周期
(一) 执行流程
- 当 servlet 首次被访问时 ,调用构造方法,只调用一次(只有一个servlet对象被创建)
- 紧接着调用初始化 init 方法,也是只调用一次
- 根据请求方式,调用 service,或 doGet 或 doPost (请求几次,就会被调用几次)
- 当应用程序停止前,调用 destroy 方法,只调用一次
注:这些方法都是有由omcat容器来调用,这种方式称之为控制反转。
(二) 配置加载项
- Servlet 默认是在第一次访问时被加载,也可以配置服务器启动时被加载 loadOnStartup = 数字。(数字代表优先级,数字小的表示优先级高)
- 可以用initParms来设置一些初始参数,然后可以在方法内直接获取到。(了解)
@WebServlet(urlPatterns = "/servlet1", loadOnStartup = 2, initParams = {
@WebInitParam(name="姓名", value = "张三"),
@WebInitParam(name="年龄", value= "18")
})
public class Servlet1 extends HttpServlet {
// @Override
// protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("执行了service");
// }
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doGet(req, resp); // 会引发 405 错误
System.out.println("执行get请求");
System.out.println(this.getInitParameter("姓名"));
System.out.println(this.getInitParameter("年龄"));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req,resp); // 会引发 405 错误
System.out.println("执行post请求");
}
public Servlet1() {
System.out.println("执行 Servlet1 构造方法");
}
@Override
public void init() throws ServletException {
System.out.println("执行初始化 init 方法");
}
@Override
public void destroy() {
System.out.println("执行销毁 destroy 方法");
}
}
(三) Servlet 2.5 以前的版本的配置
由于老版本的Servlet是没有@WebServlet注解的,所以需要添加一个在webapp/WEB-INF/目录下的web.xml文件(又称做部署描述符,需在project structure/Modules中添加)来实现部署。
<servlet>
<!-- servlet 名字 -->
<servlet-name>old</servlet-name>
<!-- servlet 对应的 java 类-->
<servlet-class>web.OldServlet</servlet-class>
<!-- 初始化参数 -->
<init-param>
<param-name>name</param-name>
<param-value>李四</param-value>
</init-param>
<!-- 让 servlet 在启动时加载,优先级是 3 -->
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<!-- servlet 名字, 与上面对应 -->
<servlet-name>old</servlet-name>
<!-- servlet 访问路径 -->
<url-pattern>/old</url-pattern>
</servlet-mapping>
二、jsp中的EL表达式
EL——expression language(表达式语言),主要作用是从作用域中取出变量并显示。
servlet页面上使用request.setAttribute("变量名", 值);
来把变量存入作用域,jsp页面上可以使用${变量名.属性}
来取出变量并显示在页面上。
(一) 做基本运算
<h3>算数运算 ${ 18 + 20 }</h3>
<h3>比较运算 ${ 18 > 20 }</h3>
<h3>逻辑运算 ${ 18 > 20 and 19 < 30 }</h3> <%--and等同与&& --%>
<h3>逻辑运算 ${ 18 > 20 or 19 < 30 }</h3> <%--or等同与|--%>
<h3>逻辑运算 ${ not (18 > 20) }</h3> <%--not等同与!--%>
<h3>三元运算 ${ (false)?"真":"假" }</h3>
<h3>空运算 ${ empty “333”}</h3> <%--有内容运算为假,无内容运算为真。或集合内有元素为假,无元素为真--%>
(二) 显示作用域中的变量
- list集合的显示
${list[下标]}——显示list集合数据
${list.size()}——等同于调用getSize()方法,显示集合大小
- map集合的显示
显示集合数据
${map.key}、${map["key"]}、${map.get("key")}
注:建议map使用字符串作为key,如果非要用整数作为key,必须用 Long, 只能用[]语法取,不能用.语法
- 显示java bean, 底层实际调用的是get方法,嵌套的对象可以多次调用.语法
显示学生对象的信息
${s1.name} ${s1.age}
${s1.homeAddress.city} ${s1.homeAddress.street}
(三) 11个隐式对象
- param 代表是请求参数的map集合,用在一个参数有一个值的情况, key对应参数名,value对应参数值
- paramValues 代表是请求参数的map集合,用在一个参数有多个值的情况, key对应参数名,value对应参数值的数组
- pageContext 页面作用域
- request 请求对象
- session 会话对象
- application 应用程序对象
- response 响应对象
- out 响应输出流
- page 当前的jsp对象(this)
- config 用来读取和jsp配置相关的信息
- exception 必须在当前页面的 page 指令中添加isErrorPage=“true”, 表示一个异常对象
(四) 标准标签库
JSTL(JSP Standard Tag Library),JSP标准标签库,可以嵌入在jsp页面中使用标签的形式完成业务逻辑等功能。jstl出现的目的同el一样也是要代替jsp页面中的脚本代码。JSTL标准标签库有5个子库,但随着发展,目前常使用的是他的核心库。
Core (核心库) 标签库的URI:http://java.sun.com/jsp/jstl/core 常用前缀:c
I18N(国际化) 标签库的URI:http://java.sun.com/jsp/jstl/fmt 常用前缀:fmt
SQL 标签库的URI:http://java.sun.com/jsp/jstl/sql 常用前缀:sql
XML 标签库的URI:http://java.sun.com/jsp/jstl/xml 常用前缀:x
Functions 标签库的URI:http://java.sun.com/jsp/jstl/functions 常用前缀:fn
- 引入标签库 jar包
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
- 在页面上声明要使用的标签库
<%@ taglib prefix="标签前缀" uri="标签的唯一标识" %>
- 核心标签库
- forEach 进行遍历
<c:forEach items="要遍历的集合" var="临时变量名" begin="起始的下标" end="结束下标" varStatus="保存下标的对象">
</c:forEach>
注:1. begin和end只能在数字遍历中出现。
2. varStatus用来对遍历出来的集合显示下标。有getIndex()和getCount()两种方法来获取下标值,getIndex()下标从0获取,getCount()下标从1获取
例:
<c:foreach items="${names} var="n" varStatus="s">
<p>${s.index}${n}</p>
结果得:
1 张三
2 李四
3 王五
- if 条件判断
<c:if test="条件">内容</c:if>
- choose 条件判断
条件多时用choose
<c:choose>
<c:when test="条件1">内容</c:when>
<c:when test="条件2">内容</c:when>
<c:when test="条件3">内容</c:when>
<c:otherwise>内容</c:otherwise>
</c:choose>
- remove 删除作用域中的变量
<c:remove var="要删除的变量名"/>
- set 把变量存入作用域
<c:set var="变量名" value="变量值"/>
- out 用来显示作用域变量
<c:out value="${变量名}"/>
<!-- 直接用el表达式,会把字符串中html进行解析,可能会导致xss攻击。利用out标签,会把字符串中的html当成普通字符串,会照原样输出,较为安全。-->
- fmt标签库
主要用来对日期和数字做格式化处理
<fmt:formatNumber value="${number}" pattern="###,###.##" />数字会自动进行四舍五入并加上一定分隔符
<fmt:formatNumber value="${number}" pattern="00000.00000"/>当数字位数不够时,会根据设置patten格式要求,自动补0。
<fmt:formatDate value="${date}" pattern="yyyy年MM月dd日 HH:mm:ss"/>根据设置patten格式要求显示日期时间
(五) jsp的底层原理和动态内容生成方式
- 底层原理
在第一次发送请求时,会把 jsp 文件转义为 java(servlet) 代码,并进一步编译为 class 文件
把页面上的静态内容(html代码),使用 out.write 方法进行打印,其中 out 对应着响应的字符输出流
至于<% 代码 %>
中的代码会原封不动搬移到 jsp 转义生成的 java 代码中
本质仍是一个 servlet - 新的动态内容生成方式
jstl 标签 + EL 表达式 - 旧的生成动态内容的方式
<% 代码 %>
称为jsp脚本, 其中的变量是方法内的局部变量<%= 表达式%>
称为jsp表达式, 用来输出值,不用加;结束
使用jsp表达式获取作用域内容<%= request.getAttribute("name") %>
使用el表达式获取作用域的内容${name}
<%! 代码 %>
jsp的声明, 其中的变量是类的成员变量- 注释
<%-- 注释内容 --%>
会阻止java代码的运行,包括 jstl 标签和 EL 表达式 都可以使用这种办法注释 <%@ 指令名 %>
- page 用来指明页面的内容类型和编码方式 , isELIgnored=“true|false” 表示是否忽略 EL 表达式
- taglib 用来引入一个标签库 prefix=“前缀” uri=“标签库的标识”
- include 用来执行页面的包含操作
<%@ include file="文件路径" %>