第 03 章 JSTL与Servlet
第 03 章 JSTL与Servlet
学习目标:
- 掌握EL表达式的应用
- 掌握常用的JSTL标签库应用
- 掌握Servlet应用(重点)
- 掌握Filter过滤器(重点、难点)。
- 常用WEB开发的实例(重点、难点)。
本章节代码将在servlet-jsp项目中的demo02中展示。
[TOC]
JSP脚本不足
比如下面的代码
<%
//每页显示的新闻列表
List<News> newsList=newsService.getPageNewsList(pageIndex, pageSize);
int i=0;
for(News news:newsList){
i++;
%>
<tr <% if(i%2!=0){%>class="admin-list-td-h2"<%} %>>
<td><%=news.getAuthor()%></td>
<td><%=news.getCreateDate() %></td>
</tr>
<%
}
%>
从上面的代码,可以看出JSP有以下缺点:
- 代码结构混乱
- 脚本与HTML混合,容易出错
- 代码不易于维护
- 使用EL表达式来优化程序代码,增加程序可读性
EL表达式
EL表达式初探
EL表达式的目的是可以通过简单的表达式语法能够获取相应作用域当中的数据。
通过指定作用域属性的key
,从而获取相应的值,这个值,包括且不限定于对象,可以是基本数据类型、字符串、集合、对象等等。如下代码所示:
<%@ page import="com.ermao.servlet.demo02.entity.Person" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: Mr.ErMao
Date: 2020/6/15 21:54
Description:
To change this template use File | Settings | File Templates.
--%>
<%-- 设置编码格式 --%>
<%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html" charset="UTF-8">
<title>EL表达式</title>
</head>
<body>
<%
// 设置对象
Person person = new Person(1,"张三",24);
// 设置普通变量
String errorMsg = "你好啊,小朋友!";
// 设置Map集合
Map<String,Object> map = new HashMap<String, Object>();
map.put("id",1);
map.put("studentName","王麻子");
map.put("studentAge",18);
// 设置List
List<Person> list = new ArrayList<Person>();
list.add(new Person(2,"李四",23));
list.add(new Person(3,"赵四",25));
list.add(new Person(4,"佟丽娅",35));
// 设置数组
String[] fruits = new String[]{"香蕉","苹果","车厘子"};
// 将上面的创建东西都设置到作用域中
// request、application、session、pageContext
request.setAttribute("person",person);
request.setAttribute("list",list);
application.setAttribute("errorMsg",errorMsg);
application.setAttribute("fruits",fruits);
session.setAttribute("student",map);
// 因为,page的作用域只能是当前的jsp页面,所以此处就不设置page的作用域了
// 将请求转发至client.jsp
request.getRequestDispatcher("client.jsp").forward(request,response);
%>
</body>
</html>
页面输出结果如下所示:
EL表达式初探EL表达式可以放在页面当中的任何位置,如:<script></script>
标签中等。但是HTML的外部资源是无法处理的,如:在引用的js文件中使用EL表达式,以及引用的css文件使用EL表达式等等。
<font style="color:red;font-weight:bolder">
【注意】:
- 如果需要获取对象的属性,那么就必须要有对应的get类型的方法。否则能够将会抛出异常
org.apache.jasper.JasperException: javax.servlet.ServletException
以及java.lang.NoSuchMethodError: com.m.entity.Person.setId(Ljava/lang/Integer;)
- 当调用不存在的对象时,EL不会报错。
</font>
EL表达式语法
从上面的代码可以看出,其基本的语法如下所示:
${EL 表达}
比如:{$person.id}
。
EL表达式操作符有下面两种:
- “
.
”,代表获取对象的属性,例如:${person.name}
; - “
[]
”,有两种使用方式:- 获取对象中的属性,例如:
${person["age"]}
; - 获取集合、数组中的对象,例如:
{${list[0]}}
以及${fruits[0]}
;
- 获取对象中的属性,例如:
<font style="color:red;font-weight:bolder">
【注意】:EL表达式是严格区分大小写。
</font>
EL表达式运算符
运算符 | 说明 | ||
---|---|---|---|
() |
改变执行的优先级,例如${3*(4+5)}
|
||
+ ,- ,* ,/ ,%
|
算术运算符,例如${3+2}
|
||
== ,!= ,> ,>= ,< ,<=
|
关系运算符,例如${a==b} 或${a eq b}
|
||
&& ,` |
, !` |
逻辑运算符,例如${true&&false}
|
|
?: |
条件运算符(三元运算),例如${a>b?1:2}
|
||
empty |
用于检测变量名是否为空,是否等于NULL ,例如${empty name}
|
关系运算符
关系运算符 | 范例 | 结果 |
---|---|---|
== 或 eq
|
${5==5} 或${5eq5}
|
true |
!= 或 ne
|
${5!=5} 或${5ne5}
|
false |
< 或 lt
|
${3<5} 或${3lt5}
|
true |
> 或 gt
|
${3>5} 或${3gt5}
|
false |
<= 或 le
|
${3<=5} 或${3le5}
|
true |
>= 或 ge
|
${3>=5} 或${3ge5}
|
alse |
总结
- EL表达式所有的关系运算符,必须在表达式内部完成。
- 当EL调用不存在的属性时,可以使用
empty
来验证某个属性是否存在,不存在则为true
。
EL表达式功能
从上面的《初探》与《运算符》中的代码中可以看出EL表达式的功能如下:
- 获取JavaBean对象的属性
- 获取数组、List、Map类型对象的元素。
- 可以使用各类算符对原始数据进行简单的处理。
- 屏蔽一些常见的异常,比如:调用不存在的属性。
- 可实现键的自动类型转换,如:
${person}
相当于(Person)request.getAttribute("person")
。
EL访问作用域
EL访问作用域的方式有两种:
- Java小脚本获取属性:
request.getAttribute("news",news)
; - 使用EL表达式:
${news}
或者${requestScope.news}
;
作用域 | Java代码取值 | EL取值 |
---|---|---|
请求作用域 | request.getAttribute("news"); |
${ requestScope.news } |
会话作用域 | session.getAttribute("username"); |
${ sessionScope.username } |
程序作用域 | application.getAttribute("count"); |
${applicationScope. count} |
页面作用域 | pageContext.getAttribute("userNum"); |
${pageScope. userNum} |
EL 表达式无法解析
当出现EL表达式无法解析时,检查下src/main/webapp/WEB-INF/web.xml
配置是否正确,因为IDEA使用maven创建web-app时,所携带的web.xml申明的版本比较低(刚好我使用Maven创建的webapp项目,web.xml里就是2.3版本的:),是无法解析EL表达式的。
<font style="color:red;font-weight:bolder">
因为在默认情况下,Servlet 2.3 / JSP 1.2是不支持EL表达式的,而Servlet 2.4 / JSP 2.0支持。
</font>
所以需要按照下面的去修改信息:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
</web-app>
或者IDEA创建目录时,添加框架支持时选择4.0 web.xml
即可解决问题
JSTL
JSTL全称JSP标准标签库(Java Server Pages Standard Tag Library)。
- JSP标准标签库;
- 实现JSP页面中的逻辑控制
关于tomcat与JSPL的版本依赖关系,可以参考《Apache Tomcat版本》
Servlet规格 | JSP规范 | EL规格 | WebSocket规范 | 认证(JASIC)规范 | Apache Tomcat版本 | 最新发行版本 | 支持的Java版本 |
---|---|---|---|---|---|---|---|
5.0 | 3.0 | 4.0 | 2.0 | 2.0 | 10.0.x | 10.0.0-M6(alpha) | 8及更高版本 |
4.0 | 2.3 | 3.0 | 1.1 | 1.1 | 9.0.x | 9.0.36 | 8及更高版本 |
3.1 | 2.3 | 3.0 | 1.1 | 1.1 | 8.5.x | 8.5.56 | 7及更高版本 |
3.1 | 2.3 | 3.0 | 1.1 | 不适用 | 8.0.x(已取代) | 8.0.53(已取代) | 7及更高版本 |
3.0 | 2.2 | 2.2 | 1.1 | 不适用 | 7.0.x | 7.0.104 | 6及更高版本(WebSocket为7及更高版本) |
2.5 | 2.1 | 2.1 | 不适用 | 不适用 | 6.0.x(已归档) | 6.0.53(已归档) | 5及更高版本 |
2.4 | 2.0 | 不适用 | 不适用 | 不适用 | 5.5.x(已存档) | 5.5.36(存档) | 1.4及更高版本 |
2.3 | 1.2 | 不适用 | 不适用 | 不适用 | 4.1.x(已归档) | 4.1.40(已归档) | 1.3及更高版本 |
2.2 | 1.1 | 不适用 | 不适用 | 不适用 | 3.3.x(已存档) | 3.3.2(已存档) | 1.1及更高版本 |
JSTL使用步骤
引入包
下载jstl1.2.jar
以及standard1.1.2.jar
两个JAR包。
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
引入标签库
<%-- 引入JSTL标签库 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
JSTL标签分类
标签库名称 | 资源标示符(uri) | 前缀(prefix) |
---|---|---|
核心标签库 | http://java.sun.com/jsp/jstl/core |
c |
国际化/格式化标签库 | http://java.sun.com/jsp/jstl/fmt |
fmt |
XML标签库 | http://java.sun.com/jsp/jstl/xml |
x |
数据库标签库 | http://java.sun.com/jsp/jstl/sql |
sql |
函数标签库 | http://java.sun.com/jsp/jstl/functions |
fn |
需要掌握的标签有:c
以及fmt
;
核心标签库
<c:if/>标签
<c:if test="${!empty person}">
<div>${person}</div>
</c:if>
test
属性:是判断条件,里面必须放el表达式
<c:forEach/> 标签
<ul>
<c:forEach items="${personList}" var="data" varStatus="status">
<li>${data}</li>
</c:forEach>
</ul>
-
items
属性:保存集合,这里写的是el表达式 -
var
属性:遍历后的元素对象 -
varStatus
:遍历的状态对象
<fmt:formatDate /> 标签
<c:if test="${!empty personList}">
<ul>
<c:forEach items="${personList}" var="data" varStatus="status">
<li>
<p>
<span style="font-weight: bolder">编号:</span>
<span>${data.getId()}</span>
</p>
<p>
<span style="font-weight: bolder">姓名:</span>
<span>${data.getName()}</span>
</p>
<p>
<span style="font-weight: bolder">年龄:</span>
<span>${data.getAge()}</span>
</p>
<p>
<span style="font-weight: bolder">生日:</span>
<span>
<fmt:formatDate pattern="yyyy-MM-dd" value="${data.getBirthday()}" />
</span>
</p>
</li>
</c:forEach>
</ul>
</c:if>
国际化/格式化标签库
标签库名称 | 资源标示符(uri) |
---|---|
<c:out /> |
输出文本内容到out对象,常用于显示特殊字符,显示默认值 |
<c:set/> |
在作用域中设置变量或对象属性的值 |
<c:remove/> |
在作用域中移除变量的值 |
<c:if/> |
实现条件判断结构 |
<c:forEach/> |
实现循环结构 |
<c:url/> |
构造url地址 |
<c:param/> |
在url后附加参数 |
<c:import/> |
在页面中嵌入另一个资源内容 |
<fmt:formatDate/> |
格式化时间 |
<fmt:formatNumber/> |
格式化数字 |
<c:if test="${!empty personList}">
<ul>
<c:forEach items="${personList}" var="data" varStatus="status">
<li>
<p>
<span style="font-weight: bolder">编号:</span>
<span>${data.getId()}</span>
</p>
<p>
<span style="font-weight: bolder">姓名:</span>
<span>${data.getName()}</span>
</p>
<p>
<span style="font-weight: bolder">年龄:</span>
<span>${data.getAge()}</span>
</p>
<p>
<span style="font-weight: bolder">生日:</span>
<span>
<fmt:formatDate pattern="yyyy-MM-dd" value="${data.getBirthday()}" />
</span>
</p>
</li>
</c:forEach>
</ul>
</c:if>
练习
使用JSP以及JSTL完成登录、注册以及修改密码的功能(可参考demo03)。实现以下功能:
- 已经存在的用户,则不能注册为用户。
参考资料
- 《JSTL 标签大全详解》,作者:冷血之,发表于:2016-11-23 21:21:39
- 《Servlet, JSP, JSTL, EL在maven中的配置》, 作者:feitu,发表于 2016-11-26