jsp和jstl
一、jsp
1.jsp的注释
JSP中一种有两种类型的注释:
1. 显式注释
能够在客户端查看的注释
1. 继承HTML风格的注释 <!-- HTML注释 -->
<!-- HTML注释 -->
2. 隐式注释
不能在客户端查看的注释
1. JSP自己的注释 <%--JSP自己的注释--%>
<%--JSP自己的注释--%>
2. 继承Java风格的注释
// 单行注释
/* 多行注释 */
<%-- Java脚本段 --%>
<%
// 这是单行注释
/* 这是多行注释 */
%>
2.Scriptlet脚本小程序
<%--
Scriptlet脚本小程序
JSP一共有三种Scriptlet脚本小程序:
第一种:Java脚本段,可以写Java代码,定义局部变量、编写语句等
<%
// 可以写Java代码
%>
生成的代码在servlet中的service方法体中
第二种:声明,声明全局变量、方法、类等
<%!
// 声明全局变量
%>
生成的代码在servlet的类体中
第三种:输出表达式,可以输出变量或字面量
<%=数值 %>
生成的代码在servlet中的service方法体中,相当于out.print()输出
--%>
<%-- 第一种:Java脚本段,可以写Java代码,定义局部变量、编写语句等 --%>
<%
// 定义局部变量
String str = "Hello Jsp";
// 输出内容到控制台
System.out.println(str);
// 输出内容到浏览器
out.print(str);
out.write("------");
// 输出全局变量
out.write("全局变量:" + num);
out.write("------");
%>
<%-- 第二种:声明,声明全局变量、方法、类等 --%>
<%!
// 声明全局变量
int num = 10;
%>
<%-- 第三种:输出表达式,可以输出变量或字面量 --%>
<%=str %>
3.jsp的指令标签
1.include静态包含
include静态包含
格式:
<%@include file="要包含的页面地址"%>
特点:
1. 将内容进行了直接的替换
2. 静态包含只会生成一个源码文件,最终的内容全部在_jspService方法体中(源码文件中)
3. 不能出现同名变量
4. 运行效率高一点点。耦合性较高,不够灵活。
<%@include file="04-header.jsp"%>
<h2>主体内容</h2>
<%
// int num = 1;
%>
<%@include file="04-footer.jsp"%>
2.include动态包含
include动态包含
格式:
<jsp:include page="要包含的页面路径"></jsp:include>
特点:
1. 动态包含相当于方法的调用
2. 动态包含会生成多个源码文件
3. 可以定义同名变量
4. 效率高,耦合度低
注:
当动态包含不需要传递参数时,include双标签之间不要有任何内容,包括换行和空格
使用动态包含传递参数
<jsp:include page="要包含的页面路径">
<jsp:param name="参数名" value="参数值"/>
</jsp:include>
注:name属性不支持表达式,value属性支持表示
获取参数:
request.getParameter(name); 通过指定参数名获取参数值
<jsp:include page="04-header.jsp"></jsp:include>
<h2>主体内容</h2>
<%
int a = 1;
%>
<jsp:include page="04-footer.jsp"></jsp:include>
<%-- 动态包含传递参数 --%>
<%
String str = "hello";
String url = "04-footer.jsp";
%>
<jsp:include page="<%=url%>">
<jsp:param name="uname" value="admin"/>
<jsp:param name="msg" value="<%=str%>"/>
</jsp:include>
<body>
<h2>头部内容</h2>
<%
int num = 1;
%>
</body>
<h2>底部内容</h2>
<%
int a = 10;
// 获取动态包含传递的参数
String uname = request.getParameter("uname");
String msg = request.getParameter("msg");
out.print(uname+","+msg);
%>
4.JSP的四大域对象
JSP的四大域对象
page作用域
在当前页面有效,跳转后无效
request作用域
在一次请求中有效,服务端跳转有效,客户端跳珠失效
session作用域
在一次会话中有效,服务端和客户端跳转有效
application作用域
在整个应用中有效
JSP中跳转方式
1. 服务端跳转
<jsp:forward page="跳转的页面地址"></jsp:forward>
2. 客户端跳转
超链接
<%
// 设置page范围的域对象
pageContext.setAttribute("name1","zhangsan");
// 设置request范围的域对象
request.setAttribute("name2","lisi");
// 设置session范围的域对象
session.setAttribute("name3","wangwu");
// 设置application范围的域对象
application.setAttribute("name4","zhaoliu");
%>
<%-- jsp中服务端跳转 --%>
<%--<jsp:forward page="06-JSP的四大域对象-02.jsp"></jsp:forward>--%>
<%-- 超链接跳转--%>
<a href="06-JSP的四大域对象-02.jsp">跳转</a>
<%
// 获取域对象中的值
out.print("page范围:" + pageContext.getAttribute("name1") + "<br>");
out.print("request范围:" + request.getAttribute("name2") + "<br>");
out.print("session范围:" + session.getAttribute("name3") + "<br>");
out.print("application范围:" + application.getAttribute("name4") + "<br>");
%>
5.El表达式
EL表达式
作用:
简化JSP代码
格式:
${域对象的名称}
操作对象:
EL表达式一般操作的是域对象,不能操作局部变量。
操作范围:
page范围
在当前页面
request范围
在一次请求
session范围
在一次会话
application范围
在整个应用程序
注:
1. 如果el表达式获取域对象的值为空,默认显示空字符串
2. el表达式默认从小到大范围去找,找到即可,如果四个范围都未找到,则显示空字符串
查找数据时可以使用四个域对象对应的空间对象,分别是:
pageScope,requestScope, sessionScope, applicationScope
<%-- 设置数据 --%>
<%
pageContext.setAttribute("uname","zhangsan"); // page作用域
request.setAttribute("uname","lisi"); // request作用域
session.setAttribute("uname","wangwu"); // session作用域
application.setAttribute("uname","zaholiu"); // application
// 定义局部变量
String str = "Hello";
%>
<%-- 获取数据 --%>
获取局部变量:${str} <br>
获取域对象:${uname} <br>
获取指定范围的域对象:<br>
page范围:${pageScope.uname}<br>
request范围:${requestScope.uname}<br>
session范围:${sessionScope.uname}<br>
application范围:${applicationScope.uname}<br>
1.EL表达式的使用
EL表达式的使用
获取List
获取List的size ${list.size()}
获取List的指定下标的值 ${list[下标]}
注:list代表的是限域变量名
获取Map
获取Map中指定key的value ${map.key} 或 ${map["key"]}
注:map代表的是限域变量名
获取JavaBean对象
获取JavaBean中的属性
${javaBean.属性名} 或 ${JavaBean对象.get属性名()}
注:JavaBean中的属性字段必须提供get方法
<%
// List
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list", list);
// Map
Map map = new HashMap();
map.put("aaa", "111");
map.put("bbb", 2222);
map.put("ccc-a", 333);
request.setAttribute("map", map);
// JavaBean对象
User user = new User();
user.setUserId(1);
user.setUname("zhangsan");
user.setUpwd("123456");
request.setAttribute("user",user);
%>
<h4>获取List</h4>
获取List的size:${list.size()} <br>
获取List的指定下标的值:${list[1]} <br>
<h4>获取Map</h4>
获取Map指定key的value值:${map.aaa} -- ${map["bbb"]}
<h4>获取JavaBean对象</h4>
获取JavaBean对象:${user}<br>
获取JavaBean中的属性:${user.uname} -- ${user.getUpwd()}
EL表达式的使用
empty
判断域对象是否为空
为空,返回true;
不为空,返回false;
如果域对象是字符串:
不存在的域对象:true
空字符串:true
null:true
如果域对象是List:
null:true
没有长度的List(size):true
如果域对象是Map:
null:true
空map对象:true
如果域对象是Javabean对象:
null:true
空对象:false
判断域对象不为空
${!empty 限域变量名}
比较两个值是否相等,返回true或false
== 或 eq
<%
// 字符串
request.setAttribute("str1","abc");
request.setAttribute("str2","");
request.setAttribute("str3",null);
// List
List list1 = new ArrayList<>();
List list2 = null;
List list3 = new ArrayList<>();
list3.add(1);
request.setAttribute("list1",list1);
request.setAttribute("list2",list2);
request.setAttribute("list3",list3);
// Map
Map map1 = null;
Map map2 = new HashMap<>();
Map map3 = new HashMap<>();
map3.put(1,2);
request.setAttribute("map1",map1);
request.setAttribute("map2",map2);
request.setAttribute("map3",map3);
// JavaBean
User user1 = null;
User user2 = new User();
User user3 = new User();
user3.setUserId(1);
request.setAttribute("user1",user1);
request.setAttribute("user2",user2);
request.setAttribute("user3",user3);
%>
<div>判断字符串是否存在</div>
${empty str} <br>
${empty str1} <br>
${empty str2} <br>
${empty str3} <br>
<hr>
<div>判断List是否为空</div>
${empty list1} <br>
${empty list2} <br>
${empty list3} <br>
<hr>
<div>Map</div>
${empty map1} <br>
${empty map2} <br>
${empty map3} <br>
<div>JavaBean对象</div>
${empty user1} <br>
${empty user2} <br>
${empty user3} <br>
<hr>
<%
request.setAttribute("a", 10);
request.setAttribute("b", 2);
request.setAttribute("c", "aa");
request.setAttribute("d", "bb");
%>
<%--
比较两个值是否相等,返回true或false
== 或 eq
--%>
${a == b }
${c == d }
${c eq d }
${a == 5 }
${c == 'aa' }
<hr>
<%--
加法: +
减法: -
乘法: *
除法: / 或 div
--%>
${a + b }
${a / b } 或 ${a div b }
<hr>
<%--
大于:>
小于:<
大于等于:>=
小于等于:<=
--%>
${a > b}
${a + 1 > 10 }
${a + b >= 10 }
${a > b && b > 5 }
${a + b > 10 || a - b > 5 }
二、jstl
1.JSTL的使用
核心标签库:
http://java.sun.com/jsp/jstl/core
包含 Web 应用的常见工作,比如:循环、表达式赋值、基本输入输出等。
格式化标签库:
http://java.sun.com/jsp/jstl/fmt
用来格式化显示数据的工作,比如:对不同区域的日期格式化等。
JSTL的使用
1. 下载JSTL所需要的jar包 (standard.jar 和 jstl.jar)
2. 在项目的web目录下的WEB-INF中新建lib目录,将jar拷贝进去
3. 选择"File",再选择"Project Structure"
4. 选择"Modules",选择右侧的"Dependencies",选择右侧的"+"号,将对应的lib目录加载进来
5. 在需要使用标签库的JSP页面通过taglib标签引入指定库
<%-- 通过taglib标签引入所需要的标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:if test="${1==1}">
Hello JSTL
</c:if>
2.if 标签
if 标签
格式:
<c:if test="<boolean>" var="<string>" scope="<string>">
...
</c:if>
常用属性:
test:条件判断,操作的是域对象,接收返回结果是boolean类型的值 (必要属性)
var:限域变量名(存放在作用域中的变量名),用来接收判断结果的值(可选属性)
scope:限域变量名的范围(page、request、session、application)(可选属性)
注:
1. 标签操作的一般都是域对象
2. if标签标签没有else,如果想要else的效果,就需要设置两个完全相反的条件
<%
// 设置数据
request.setAttribute("num",0);
%>
<c:if test="${num > 0}" >
数值大于0
</c:if>
<c:if test="${num <= 0}">
数值不大于0
</c:if>
<br>
<c:if test="${num > 100}" var="flag" scope="request"></c:if>
${flag}-- ${requestScope.flag} -- ${sessionScope.flag}
3.choose、when 和 otherwise 标签
choose、when 和 otherwise 标签
格式:
<c:choose>
<c:when test="<boolean>">
...
</c:when>
<c:when test="<boolean>">
...
</c:when>
...
...
<c:otherwise>
...
</c:otherwise>
</c:choose>
属性:
1. choose标签没有属性
2. when标签只有一个test属性,必须属性
3. otherwise标签没有属性
注意:
1. choose标签和otherwise标签没有属性,而when标签必须有一个test属性
2. choose标签中必须包含至少一个when标签,可以没有otherwise标签 (Illegal "choose" without child "when" tag)
3. otherwise标签必须设置在最后一个when标签之后 (Illegal "c:when" after "c:otherwise" tag in "c:choose" tag.)
4. choose标签中只能设置when标签与otherwise标签(Illegal child tag in "c:choose" tag: "c:if" tag)
5. when标签和otherwise标签中可以嵌套其他标签
6. otherwise标签会在所有的when标签不执行时才会执行
<%
request.setAttribute("score",90);
%>
<c:choose>
<c:when test="${score < 60}">
<h2>你个小渣渣!</h2>
</c:when>
<c:when test="${score == 60}">
<h2>分不在高,及格就行!</h2>
<c:if test="${1==1}">111</c:if>
</c:when>
<c:when test="${score > 60 && score < 80}">
<h2>哎哟不错哦!</h2>
</c:when>
<c:otherwise>
<h2>你很棒棒哦!</h2>
<c:if test="${1==1}">111</c:if>
</c:otherwise>
</c:choose>
4.forEach标签
forEach标签
格式:
<c:forEach
items="<object>"
begin="<int>"
end="<int>"
step="<int>"
var="<string>"
varStatus="<string>">
</c:forEach>
属性:
begin:开始数
end:结束数
step:间隔数
var:限域变量名,用来接收当前遍历的成员
items:要循环的数据(数组、List、Map等)
forEach varStatus 属性
index: 当前这次迭代从 0 开始的迭代索引
count: 当前这次迭代从 1 开始的迭代计数
first: 用来表明当前这轮迭代是否为第一次迭代的标志
last: 用来表明当前这轮迭代是否为最后一次迭代的标志
1. 迭代主体内容多次
<c:forEach begin="开始数" end="结束数" step="间隔数" var="限域变量名">
</c:forEach>
相当于Java中for...int
for (int i = 0; i < 10; i++) {
}
2. 循环
<c:forEach items="要被循环的数据" var="限域变量名">
</c:forEach>
相当于Java中的foreach
for(String str : list) {
}
<%-- 迭代主体内容多次 --%>
<c:forEach var="i" begin="1" end="10" step="2">
${i}
</c:forEach>
<hr>
<%-- 循环 --%>
<%
List<String> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list.add("A:" + i);
}
pageContext.setAttribute("li", list);
%>
<c:forEach items="${li}" var="item">
${item}
</c:forEach>
<hr>
<table align="center" width="800" border="1" style="border-collapse: collapse;">
<tr>
<th>名称</th>
<th>当前成员下标</th>
<th>当前成员循环数</th>
<th>是否第一次被循环</th>
<th>是否最后一次被循环</th>
</tr>
<c:forEach items="${li}" var="item" varStatus="itemp">
<tr>
<td>${item}</td>
<td>${itemp.index}</td>
<td>${itemp.count}</td>
<td>${itemp.first}</td>
<td>${itemp.last}</td>
</tr>
</c:forEach>
</table>
<hr>
<%-- 循环对象集合 --%>
<%
List<User> userList = new ArrayList<User>();
User user = new User(1,"zhangsan","123456");
User user2 = new User(2,"lisi","123321");
User user3 = new User(3,"wangwu","654321");
userList.add(user);
userList.add(user2);
userList.add(user3);
// 将数据设置到作用域中
request.setAttribute("userList", userList);
%>
<%-- 判断集合是否为空 --%>
<c:if test="${!empty userList}">
<%-- 当集合不为空时,遍历集合 --%>
<table align="center" width="800" border="1" style="border-collapse: collapse;">
<tr>
<th>用户编号</th>
<th>用户名称</th>
<th>用户密码</th>
<th>用户操作</th>
</tr>
<c:forEach items="${userList}" var="user">
<tr align="center">
<td>${user.userId}</td>
<td>${user.uname}</td>
<td>${user.upwd}</td>
<td><button>修改</button></td>
</tr>
</c:forEach>
</table>
</c:if>
<%-- 循环Map --%>
<%
Map<String,Object> map = new HashMap<>();
map.put("map1", "aaa");
map.put("map2", "bbb");
map.put("map3", "ccc");
pageContext.setAttribute("map", map);
%>
<c:forEach items="${map}" var="m">
key:${m.key} value:${m.value} <br>
</c:forEach>
5.格式化动作标签
格式化动作标签
formatNumber标签
将数值型转化成指定格式的字符串
语法格式:
<fmt:formatNumber
value="<string>"
type="<string>"
var="<string>"
scope="<string>"/>
常用属性:
value:要格式化的数值
type:要格式化的类型
number 数值型 (默认)
percent 百分比类型
currency 货币类型
var:限域变量名,用来接收格式化后的结果
scope:var属性的范围 (page|request|session|apllication)
注:
1. 如果使用了var属性,标签不会输出结果,需要通过el表达式获取
2. 默认的类型(type)的取值为number
formatDate标签
将Date型的数据转化成指定格式的字符串
语法格式:
<fmt:formatDate
value="<string>"
type="<string>"
dateStyle="<string>"
timeStyle="<string>"
pattern="<string>"
timeZone="<string>"
var="<string>"
scope="<string>"/>
常用属性:
value:要格式化的日期
type:格式化的类型
date 日期型 年月日
time 时间型 时分秒
both 日期时间型
dateStyle:日期格式
timeStyle:日期时间
pattern:自定义模式
y M d H m s
timeZone
var
scope
parseNumber标签
将指定格式的数值字符串转化成数值型
语法格式:
<fmt:parseNumber
value="<string>"
type="<string>"
var="<string>"
scope="<string>"/>
parseDate标签
将日期型的字符串转换成Date型
格式语法:
<fmt:parseDate
value="<string>"
type="<string>"
dateStyle="<string>"
timeStyle="<string>"
pattern="<string>"
var="<string>"
scope="<string>"/>
<fmt:formatNumber value="10" type="number" var="num" /> ${num } <br>
<fmt:formatNumber value="10" type="percent" /> <br>
<fmt:formatNumber value="10" type="currency" /> <br>
<!-- 设置时区 -->
<fmt:setLocale value="en_US"/>
<fmt:formatNumber value="10" type="currency" /> <br>
<hr>
<%-- 格式化日期 --%>
<%
request.setAttribute("myDate",new Date());
%>
${myDate} <br>
<fmt:formatDate value="${myDate}" /> <br>
<fmt:formatDate value="${myDate}" type="date" /> <br>
<fmt:formatDate value="${myDate}" type="time" /> <br>
<fmt:formatDate value="${myDate}" type="both" /> <br>
<fmt:formatDate value="${myDate}" type="both" dateStyle="FULL" /> <br>
<fmt:formatDate value="${myDate}" type="both" timeStyle="short" /> <br>
<fmt:formatDate value="${myDate}" pattern="yyyy-MM-dd" /> <br>
<hr>
<fmt:setLocale value="zh_CN"/>
<fmt:parseNumber value="100" /> <br>
<fmt:parseNumber value="100" type="number" /> <br>
<fmt:parseNumber value="100%" type="percent" /> <br>
<fmt:parseNumber value="¥10.00" type="currency" /> <br>
<hr>
<fmt:parseDate value="2020-01-06" type="date" /> <br>
<fmt:parseDate value="2020/01/06" pattern="yyyy/MM/dd" /> <br>
<%-- 引入格式化标签库 --%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>