一. EL
1. 介绍
EL:Expression Language ,可以代替JSP页面中的JAVA代码
servlet(增加数据)—》jsp(显示数据)
传统思维· 在JSP中代码显示数据的弊端:1. 类型转换,2. 需要处理null, 3. 代码掺杂
El不需要类型转换,遇到null不会显示,
2. 原理
EL实例-------是通过get方法,不是属性(内部包装过)
没有对应get方法,报异常:Property 'shuxing' not readable on type
org.student.entity.Student
private int shuxing;
// public int getShuxing() {
// return shuxing;
// }
public void setShuxing(int shuxing) {
this.shuxing = shuxing;
}
3. 基础零
(1) 禁用
- 如果EL表达式被禁用,在页面最上面,加上:
isELIgnored="false"
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
- web.xml里设置
<!-- 全局配置 el表达式有效 -->
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>false</el-ignored>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
(2) +区别
<%= %>,${}
的+
的差别
<body>
<%="2"+"2"%><br>
<%='2'+'2'%><br>
${"2"+"2"}<br>
${'2'+'2'}<br>
</body>
结果;
22
100
4
4
<%= %> 与sout差不多(字符串拼接,char型对应ascii码数字相加), ${} 是统一强转为数字(当然必须可以强转为数字,不然执行不了加法,抛异常),
(3) 关系,逻辑运算符
(4) empty 运算符
${ empty 对象 } 返回结果为Boolean值
只要满足下面三个条件都返回true
1.对象为null
2.字符串为””
3.集合长度否为0
4. 基础一
- 初步使用:
作用域对象:
pageContext,request,session,application
对应的EL中对象:
pageScope,requestScope,sessionScope,appicationScope
两者运用区别:
<%
pageContext.setAttribute("key", "pageValue");
request.setAttribute("key", "requestValue");
session.setAttribute("key", "SessionValue");
application.setAttribute("key", "applicationValue");
%>
<hr>
<%=pageContext.getAttribute("key")%><br>
<%=request.getAttribute("key")%><br>
<%=session.getAttribute("key")%><br>
<%=application.getAttribute("key")%><br>
<%=pageContext.findAttribute("key")%><br>
<hr>
<h3>EL</h3>
${pageScope.key }<br>
${requestScope.key }<br>
${sessionScope.key }<br>
${applicationScope.key }<br>
${key } 等价 pageContext.findAttribute("key") -
${requestScope.student.address.schooladd}
${域对象.域对象中的属性.属性.属性.级联属性}
自动获取对应类:((User)pageContext.findAttribute(“user”)).getUsername();
EL操作符:
3. 点操作符 .
1.1 使用简单
4. 中括号操作符 [ ]
2.1 功能强大:可以包含特殊字符( . - ,)
2.2 可以访问数据(获取数组的元素)
2.3 获取变量值(例如存在变量String name=“my-name”;可以 ${requestScope[name]} ),
5. 获取集合
Map<String, Object> map = new HashMap<>();
map.put("cn", "中国");
map.put("us", "美国");
request.setAttribute("map", map);
${requestScope.map.cn}<br/>
${requestScope.map["us"]}<br/>
${requestScope.map}
只获取对象,直接得到对应tostring方法的值
5. 基础二
EL的表达式的隐式对象(不需要new 就能使用的对象,自带的对象)
a. 作用域访问对象(EL域对象)
pageScope requestScope sessionScope applicationScope
对应jsp的四个范围
如果不指定域对象,则默认会根据从小到大的顺序,依次取值 :pageScope< requestScope <sessionScope<applicationScope
b. 参数访问对象:获取表单数据
(超链接里传的值 a.jsp?a=b&c=d ,地址栏中的值一回事 a.jsp?a=b&c=d )
(request.getParameter(), request.getParameterValues(),)
${param} ${paramValues}
c. JSP隐式对象pageContext 相当于桥梁
- 在jsp中可以通过pageContest 获取其他的jsp隐式对象
- 如果在EL中使用jsp隐式对象,通过pageContext获取
${pageContext.request}
p a g e C o n t e x t . g e t S e s s i o n ( ) 但 是 在 E L 中 调 用 的 是 方 法 ‘ {pageContext.getSession()} 但是在EL中调用的是方法 ` pageContext.getSession()但是在EL中调用的是方法‘{pageContext.session}级联获取(获取后通过对象继续获取) **
${pageContext.request.serverPort}`**
${pageContext.方法名去掉()和get并且将首字母小写}------------自动调用对应方法
d. 表单数据 ${param.name} ${paramValues.name}
request.getParameter(String name)和 request.getParameterValues(String name)
取得用户在表单中输入的数据,但在EL中可以使用隐含对象param和paramValues
来取得数据。如下所示:
${param.name} ${paramValues.name}
6. 整体代码
1.实体类
package org.student.entity;
public class Student {
private Address address;
private int no;
private String name;
private int shuxing;
public int getShuxing() {
return shuxing;
}
public void setShuxing(int shuxing) {
this.shuxing = shuxing;
}
public Student() {
}
public Student(Address address, int no, String name) {
super();
this.address = address;
this.no = no;
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [address=" + address + ", no=" + no + ", name=" + name + "]";
}
}
package org.student.entity;
public class Address {
// 学校地址
private String schooladd;
// 家庭地址
private String shengadd;
public Address() {
}
public Address(String schooladd, String shengadd) {
super();
this.schooladd = schooladd;
this.shengadd = shengadd;
}
public String getSchooladd() {
return schooladd;
}
public void setSchooladd(String schooladd) {
this.schooladd = schooladd;
}
public String getShengadd() {
return shengadd;
}
public void setShengadd(String shengadd) {
this.shengadd = shengadd;
}
}
2.servlet
package org.student.servlet;
import org.student.entity.Address;
import org.student.entity.Student;
@WebServlet("/ELInitServlet")
public class ELInitServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Address address = new Address();
address.setSchooladd("xian");
address.setShengadd("beijing");
Student student = new Student();
student.setNo(1);
student.setName("lisi");
student.setAddress(address);
// 放入数据
request.setAttribute("student", student);
// 放入有特殊字符的数据
request.setAttribute("my-name", "liwei");
// 放入数组
String[] hobbies = new String[] {"football","pingpang","basketball"};
request.setAttribute("hobbies", hobbies);
// 放入Map集合
Map<String, Object> map = new HashMap<>();
map.put("cn", "中国");
map.put("us", "美国");
request.setAttribute("map", map);
// 放null
request.setAttribute("nullValue", null);
// 放session
request.getSession().setAttribute("sessionKey", "sessionValue");
// 请求转发
request.getRequestDispatcher("el.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
3.servlet跳转的页面el.jsp
<body>
<%
Student student = (Student)request.getAttribute("student");
out.print(student+"<br/>");
out.print(student.getNo()+"<br/>");
out.print(student.getName()+"<br/>");
out.print(student.getAddress()+"<br/>");
out.print(student.getAddress().getSchooladd()+"<br/>");
out.print(student.getAddress().getShengadd()+"<br/>");
%>
<%!
String name="my-name";
%>
----获取参数对象----<br/>
${param.uanme}<br/>
${paramValues.hobbies[0]}<br/>
${paramValues.hobbies[1]}<br/>
${paramValues.hobbies[2]}<br/>
----点操作符----<br/>
${requestScope.student}<br/>
获取属性出错,在没有对应getter方法时 ${requestScope.student.shuxing}<br/>
${requestScope.student.no}<br/>
${requestScope.student.name}<br/>
${requestScope.student.address.schooladd}<br/>
${requestScope.student.address.shengadd}<br/>
----中括号[" "] [' ']操作符----<br/>
${requestScope.student.address["shengadd"]}<br/>
${requestScope.student["address"]["shengadd"]}<br/>
${requestScope.student['address']['shengadd']}<br/>
----包含特殊字符操作符 .是有缺陷的----<br/>
.获取 ${requestScope.my-name}<br/>
[]获取 ${requestScope['my-name']}<br/>
----[]可以放变量----<br/>
${requestScope[name]}<br/>
----[]可以获取数组----<br/>
${requestScope.hobbies[0]}<br/>
${requestScope.hobbies[1]}<br/>
${requestScope.hobbies[2]}<br/>
----获取集合----<br/>
${requestScope.map.cn}<br/>
${requestScope.map["us"]}<br/>
----逻辑运算----<br/>
${3 > 2},${3 gt 2}, <br/>
${3>2 || 3<2 }, ${3>2 or 3<2 }<br/>
----empty运算----<br/>
${empty requestScope['my-name']}<br/>
${empty requestScope.hellword}<br/>
${empty requestScope.nullValue}<br/>
----session对象----<br/>
${sessionScope['sessionKey']}<br/>
----默认对象----<br/>
${sessionKey}<br/>
----获取JSP隐式对象----<br/>
${pageContext.request.serverPort}
</body>
二. JSTL
1. 引入tablib:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix = “c”:是前缀
核心标签库:通用标签库,条件标签库,迭代标签库
2. 通用标签库
2.1 <c:set>赋值
scope:
作用域范围:page,request,session,application
作用域对象:pageContext,request,session,application
a. 在某个作用域中(4个范围对象),给某个变量赋值
request.setAttribute("name", "zhangsan" );
等价:
<c:set var="name" value="zhangsan" scope="request"/>
<c:set var="变量名" value="变量值" scope="4个范围对象的作用域"/>
没有指定scope时,默认放入pageContext
b.
- 给普通对象赋值: 在某个作用域中(4个范围对象),给某个变量的属性 赋值,下面这种写法不需指定 scope=“request”。target已经指定了
<c:set target="${作用域.对象名}" property="对象属性" value="给对象赋的新值" />
<c:set target="${requestScope.student}" property="name" value="zhangsan1" />
- 给Map对象赋值:
<c:set target="${requestScope.map}" property="cn" value="China" />
- 可以给不存在变量赋值,即直接新加变量
不可以给不存在对象赋值
<%--错误--%>
<c:set target="${requestScope.xxx}" property="y" value="x" />
可以给不存在变量赋值
<c:set var="x" value="y" scope="request"/>
2.2 c:out :显示
- 提供默认值 , 显示不存在的数据时,如果有defult,显示default的值:
<c:out value="${requestScope.age1}" default="没有此值"></c:out>
${requestScope.age1}
- 处理特殊标记
escapeXml="true"
,原样显示
<c:set var="age2" scope="request" value="<h1>hahha</h1>"></c:set>
<%--首先反编译value :<h1>hahha</h1> --%>
<c:out value="${requestScope.age2}" escapeXml="true"></c:out>
<%--直接输出 <h1>hahha</h1> 被html 识别--%>
${requestScope.age2}
2.3 c:remove :删除属性
<c:remove var="a" scope="request"/>
3. 选择
在test里的双引号里 不要有多的空格,相当于java打印的效果: test="${10>3} "
1. if
格式:
<c:if test="<boolean>" var="<string>" scope="<string>">
...
</c:if>
示例:
<c:set var="salary" scope="session" value="${2000*2}"/>
<c:if test="${salary > 2000}">
<p>我的工资为: <c:out value="${salary}"/><p>
</c:if>
2. c:choose, c:when, c:otherwise 标签
<c:choose>
标签与Java switch语句的功能一样,用于在众多选项中做出选择。
<c:choose>
<c:when test="<boolean>">... </c:when>
<c:when test="<boolean>">... </c:when>
...
<c:otherwise> ... </c:otherwise>
</c:choose>
示例:
<c:choose>
<c:when test="${score>=90 }">优秀</c:when>
<c:when test="${score>=75 }">良好</c:when>
<c:when test="${score>=60 }">一般</c:when>
<c:otherwise>
较差
</c:otherwise>
</c:choose>
4. 循环(迭代标签库)
1. c:forEach
<c:forEach
items="<object>" 要被循环的值
begin="<int>" 开始的元素(0=第一个元素,1=第二个元素)
end="<int>" 最后一个元素(0=第一个元素,1=第二个元素)默认值: Last element
step="<int>" 每一次迭代的步长,默认值:1,(i++)
var="<string>" 代表当前条目的变量名称
varStatus="<string>"> 代表循环状态的变量名称
示例:
<c:forEach
items="${sessionScope.userList}"
var="userItem"
begin="1"
end="10"
step="3"
varStatus="userStatus"> XXX </c:foreach>
对 session 对象存储的 userList 集合对象进行遍历,每次访问的项暂时存储在 userItem 变量中,从索引 1 开始至索引 10 进行访问,但不是依次访问,每隔 3 个元素访问一次。每次访问项的状态相关值由 userStatus 对象暂存。
${userStatus.index} 此项的索引,从0开始 (代表索引,相当于var)
${userStatus.count} 此项的计数序号,从1开始 (代表第几次循环)
${userStatus.first} 此项是否是第一项,布尔值
${userStatus.last} 此项是否是最后一项,布尔值
如果说希望直接循环 ${sessionScope.userList} 中的数据,我们就可以不用加 begin 和 end:
<c:forEach items="${sessionScope.userList}" var="userItem" varStatus="userStatus">
${userItem.键名}
</c:forEach>
2. c:forTokens
delims
: 分隔符,必须存在,无默认值
items:是字符串
<c:forTokens items="google,runoob,taobao" delims="," var="name">
<c:out value="${name}"/><p>
</c:forTokens>
结果:
google
runoob
taobao
5. c:url标签
<c:url>标签将URL格式化为一个字符串,然后存储在一个变量中。
这个标签在需要的时候会自动重写URL。
var属性用于存储格式化后的URL。
<c:url>标签只是用于调用response.encodeURL()方法的一种可选的方法。
<c:url context="/web03" scope="page" var="address" value="/index.jsp"></c:url>
6. c:import 标签
<c:import>标签提供了所有jsp:include行为标签所具有的功能,同时也允许包含绝对URL。
举例来说,使用<c:import>标签可以包含一个FTP服务器中不同的网页内容。
<%--包含页面 --%>
<c:import url="add.jsp"></c:import>
三. 猜数字游戏:
<%@ page import="java.util.Random" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>猜一猜</title>
</head>
<body>
<%
int i = new Random().nextInt(10);
/*每一次在本页面生成随机数*/
pageContext.setAttribute("cai",i);
%>
<%--在玩一次--%>
<c:if test="${!empty param.redo}">
<c:remove var="cai" scope="session"></c:remove>
</c:if>
<%--判断session是否需要更新--%>
<c:if test="${empty sessionScope.cai}">
<c:set var="cai" value="${pageScope.cai}" scope="session"></c:set>
</c:if>
<form action="" method="post">
<p>
请输入您猜的数(1-10):<input name="number" type="text"><br>
<input type="submit" value="提交"><br>
</p>
</form>
<form action="" method="post">
<input type="hidden" value="redo" name="redo">
<input value="再玩一次" type="submit">
</form>
<div style="color: blue;font-size: 30px">
<c:if test="${sessionScope.cai > param.number}">
<c:out value="猜小了"></c:out>
</c:if>
<c:if test="${sessionScope.cai < param.number}">
<c:out value="猜大了"></c:out>
</c:if>
<c:if test="${sessionScope.cai == param.number}">
<c:out value="正确"></c:out>
</c:if>
</div>
</body>
</html>