共计 12848 个字符,预计需要花费 33 分钟才能阅读完成。
typora-root-url: images
typora-copy-images-to: images
JSP 和 JSTL
次要内容
JSP
JSP 的根底语法
简介
JSP:Java Server Page SUN 公司提供的动静网页编程技术,是 Java Web 服务器端的动静资源。
它相比 html 而言,html 只能为用户提供静态数据,而 Jsp 技术容许在页面中嵌套 java 代码,为用户提供动态数据。
相比 servlet 而言,servlet 很难对数据进行排版,而 jsp 除了能够用 java 代码产生动态数据的同时,也很容易对数据进行排版。
不论是 JSP 还是 Servlet,尽管都能够用于开发动静 web 资源。但因为这 2 门技术各自的特点,在长期的软件实际中,人们逐步把 servlet 作为 web 利用中的控制器组件来应用,而把 JSP 技术作为数据显示模板来应用。
其实 Jsp 就是一个 Servlet,当咱们第一次拜访 Jsp 的时候,Jsp 引擎都会将这个 Jsp 翻译 成一个 Servlet,这个文件寄存在 tomcat(源码目录)中的 work 目录中。
筹备工作
配置 IDEA
这一步不是必须的,当然因为 编辑器中有些默认的配置项咱们感觉不是很完满,比方 ” 编码格局 ”、页面模板等。咱们能够在新建 JSP 页面之前就先批改为咱们须要的。
1. 抉择 ”File” —> “Settings…”
2. 设置编码格局。搜寻 ”encode”,抉择 ”File Encoding”
3. 设置页面模板。搜寻 ”template”,抉择 ”File and Code Templates”,抉择右侧的 ”Other”,抉择下方的 ”Jsp File”
新建 JSP 页面
正文
在 JSP 中反对两种正文的语法操作:
一种是显示正文,这种正文是容许客户端看见的;另一种是隐式正文,此种正文是客户端无奈看见的
① 显示正文语法:从 HTML 格调继承而来
② 隐式正文语法:从 JAVA 格调继承;JSP 本人的正文
JSP 的三种正文形式:
1)// 正文,单行正文 / 多行正文/
2)<!– HTML 格调的正文 –>
3)<%– JSP 正文 –%>
Scriptlet
在 JSP 中最重要的局部就是 Scriptlet(脚本小程序 ), 所有嵌入在 HTML 代码中的 Java 程序。
在 JSP 中一共有三种 Scriptlet 代码:都必须应用 Scriptlet 标记进去
第一种:<% %>:java 脚本段,能够定义局部变量、编写语句
第二种:<%! %>:申明,能够定义全局(成员)变量、办法、类
第三种:<%= %>:表达式,数据一个变量或具体内容
通过观察解析为 java 文件的 jsp 代码了解三种小脚本
<%@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″%>
<!DOCTYPE >
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>Scriptlet</title>
</head>
<body>
<%
String str = “Hello JSP”;
System.out.println(str);
response.getWriter().write(str);
%>
<%!
String memberStr = “a member String”;
%>
<%=memberStr%>
<h1>This is a JSP page!!</h1>
</body>
</html>
JSP 的指令标签
应用蕴含操作,能够将一些反复的代码蕴含进来持续应用,从失常的页面组成来看,有时可能分为几个区域。而其中的一些区域可能是始终不须要扭转的,扭转的就其中的一个具体内容区域。当初有两种办法能够实现上述性能。
办法一:在每个 JSP 页面(HTML)都蕴含工具栏、头部信息、尾部信息、具体内容
办法二:将工具栏、头部信息、尾部信息都分成各个独立的文件,应用的时候间接导入
很显著,第二种办法比第一种更好,第一种会存在很多反复的代码,并且批改很不不便,在 JSP 中如果要想实现蕴含的操作,有两种做法:动态蕴含 、 动静蕴含,动态蕴含应用 include 指令即可,动静蕴含则须要应用 include 动作标签。
include 动态蕴含
<%@ include file=” 要蕴含的文件门路 ” %> <!– 相对路径 –>
例如:
<%@include file=”include.jsp” %>
或
<%@include file=”include.html” %>
动态蕴含就是将内容进行了间接的替换,就好比程序中定义的变量一样,是在 servlet 引擎转译时,就把此文件内容蕴含了进去(两个文件的源代码整合到一起,全副放到_jspService 办法中),所以只生成了一个 servlet,所以两个页面不能有同名的变量。运行效率高一点点。耦合性较高,不够灵便。
include 动静蕴含
动静蕴含在代码的编译阶段,蕴含和被蕴含局部是两个独立的局部,只有当运行时,才会动静蕴含进来,好比办法的调用。
<jsp:include page=”include.jsp”></jsp:include>
留神 :动静蕴含,中 间不要加任何内容,包含空格,除非确认要应用参数,否则报错!
<jsp:include page=”include.html”></jsp:include>
<%
String a = “hello.jsp”;
%>
<jsp:include page=”<%=a %>”></jsp:include>
应用动静蕴含还能够通过在页面之间传参。
接管参数通过 request.getParameter(name);
<jsp:include page=”hello.jsp” flush=”true”>
<jsp:param name=”uname” value=”zhangsan”/>
</jsp:include>
hello.jsp
<!– 接管参数 –>
<%=request.getParameter(“uname”)%>
JSP 的四大域对象
四种属性范畴
在 JSP 中提供了四种属性的保留范畴,所谓的属性保留范畴,指的就是一个设置的对象,能够再多少个页面中保留并能够持续应用
- page 范畴
pageContext : 只在一个页面中保留属性,跳转之后有效
- request 范畴
request : 只在一次申请中保留,服务器跳转后仍然无效
- session 范畴
session : 在一次会话范畴中,无论何种跳转都能够应用
- application 范畴
application : 在整个服务器上保留
办法
类型
形容
public void setAttribute(String name, Object o)
一般
设置属性的名称及内容
public Object getAttribute(String name)
一般
依据属性名称取属性
public void removeAttribute(String name)
一般
删除指定的属性
验证属性范畴的特点
- page
本页面获得,服务器端跳转(<jsp :forward>)后有效
- request
服务器跳转无效,客户端跳转有效
如果是客户端跳转,则相当于收回了两次申请,那么第一次的申请将不存在了;如果心愿不论是客户端还是服务器跳转,都能保留的话,就须要持续扩大范围。
- session
无论客户端还是服务器端都能够获得,然而当初从新开启一个新的浏览器,则无奈获得之前设置的 session 了,因为每一个 session 只保留在以后的浏览器当中,并在相干的页面获得。
对于服务器而言,每一个连贯到它的客户端都是一个 session
如果想要让属性设置一次之后,不论是否是新的浏览器关上都能获得则能够应用 application
- application
所有的 application 属性间接保留在服务器上,所有的用户 (每一个 session) 都能够间接拜访获得
只有是通过 application 设置的属性,则所有的 session 都能够获得,示意公共的内容,然而如果此时服务器重启了,则无奈获得了,因为敞开服务器后,所有的属性都隐没了,所以须要从新设置。
问:应用哪个范畴呢?
答:在正当范畴尽可能小
EL 表达式的应用
EL 表达式的语法
EL(Expression Language)是为了使 JSP 写起来更加简略。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的办法,让 Jsp 的代码更加简化。
语法结构非常简单:${expression}
EL 表达式个别操作的都是域对象中的数据,操作不了局部变量。
域对象的概念在 JSP 中一共有四个:pageContext, request, session, application;范畴顺次是,本页面 , 一次申请 , 一次会话 , 整个应用程序。
当须要指定从某个特定的域对象中查找数据时能够应用四个域对象对应的空间对象,别离是:pageScope, requestScope, sessionScope, applicationScope。
而 EL 默认的查找形式为从小到大查找,找到即可。当域对象全找完了还未找到则返回空字符串 ””。
EL 表达式的应用
获取数据
设置域对象中的数据
<%
pageContext.setAttribute(“uname”,”zhangsan”); // page 作用域
request.setAttribute(“uname”,”lisi”); // request 作用域
session.setAttribute(“uname”,”wangwu”); // session 作用域
application.setAttribute(“uname”,”zaholiu”); // application
%>
获取域对象的值
<%– 获取域对象中的数据:默认查找形式为从小到大,找到即止。若四个范畴都未找到,则返回空字符串。–%>
${uname} <!– 输入后果为:zhangsan –>
获取指定域对象的值
${pageScope.uname} <!– page 作用域 –>
${requestScope.uname} <!– request 作用域 –>
${sessionScope.uname} <!– session 作用域 –>
${applicationScope.uname} <!– application 作用域 –>
获取 List
<%
List<String> list = new ArrayList<String>();
list.add(“aaa”);
list.add(“bbb”);
list.add(“ccc”);
request.setAttribute(“list”, list);
%>
<%–
获取 List 中指定下标的数据
${list[下标] }
获取汇合的长度
${list.size()}
注:list 代表的是存在域对象中的变量名(限域变量名)
–%>
${list[1] }
获取 Map
<%
Map map = new HashMap();
map.put("aaa", "111");
map.put("bbb", 2222);
map.put("ccc-a", 333);
request.setAttribute("map", map);
%>
<%–
获取 Map 中指定值
${map["key"] } 或 ${map.key}
注:map 代表的是存在域对象中的变量名(限域变量名)
–%>
${map.aaa}
${map[“bbb”]}
获取 JavaBean 对象
User.java
public class User {
private Integer userId;
private String uname;
private String upwd;
public Integer getUserId() {return userId;}
public void setUserId(Integer userId) {this.userId = userId;}
public String getUname() {return uname;}
public void setUname(String uname) {this.uname = uname;}
public String getUpwd() {return upwd;}
public void setUpwd(String upwd) {this.upwd = upwd;}
}
<%
User user = new User();
user.setUserId(1);
user.setUname("zhangsan");
user.setUpwd("123456");
request.setAttribute("user",user);
%>
<%– JavBean 中的属性字段须要提供 get 办法 –%>
${user} <%– 获取对象 –%>
${user.uname} <%– 获取对象中的属性 –%>
empty
<%–
empty
判断域对象是否为空。为空,返回 true;不为空返回 false;${empty 限域变量名}
判断对象是否不为空。${!empty 限域变量名}
–%>
${empty uname}
${empty list}
${empty map}
${empty user}
EL 运算
<%
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’}
算术运算
<%–
加法:+
减法:-
乘法:*
除法:/ 或 div
–%>
${a + b}
${a / b} 或 ${a div b}
大小比拟
<%–
大于:>
小于:<
大于等于:>=
小于等于:<=
–%>
${a > b}
${a + 1 > 10}
${a + b >= 10}
${a > b && b > 5}
${a + b > 10 || a – b > 5}
JSTL
标签的应用
Java Server Pages Standard Tag Libray(JSTL):JSP 规范标签库,是一个定制标签类库的汇合,用于解决一些常见的问题,例如迭代一个映射或者汇合、条件测试、XML 解决,甚至数据库和拜访数据库操作等。
咱们当初只探讨 JSTL 中最重要的标签,迭代汇合以及格式化数字和日期几个标签。
外围标签库:
http://java.sun.com/jsp/jstl/core
蕴含 Web 利用的常见工作,比方:循环、表达式赋值、根本输入输出等。
格式化标签库:
http://java.sun.com/jsp/jstl/fmt
用来格式化显示数据的工作,比方:对不同区域的日期格式化等。
为了在 JSP 页面应用 JSTL 类库,必须以下列格局应用 taglib 指令:
<%@taglib uri=”” prefix=”” %>
例如:
<%@taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %>
前缀能够是任意内容,遵循标准能够使团队中由不同人员编写的代码更加类似;所以,倡议应用当时设计好的前缀。
此时须要导入两个 jar 包
从 Apache 的规范标签库中下载的二进包(jakarta-taglibs-standard-current.zip)。
官网下载地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
下载 jakarta-taglibs-standard-1.1.2.zip 包并解压,将 jakarta-taglibs-standard-1.1.2/lib/ 下的两个 jar 文件:standard.jar 和 jstl.jar 文件拷贝到我的项目的指定目录下。
条件动作标签
条件动作指令用于解决页面的输入后果依赖于某些输出值的状况,在 Java 中是利用 if、if…else 和 switch 语句来进行解决的。在 JSTL 中也有 4 个标签能够执行条件式动作指令:if、choose、when 和 otherwise。
if 标签
if 标签先对某个条件进行测试,如果该条件运算后果为 true, 则解决它的主体内容,测试后果保留在一个 Boolean 对象中,并创立一个限域变量来援用 Boolean 对象。能够利用 var 属性设置限域变量名,利用 scope 属性来指定其作用范畴。
语法格局
<c:if test=”<boolean>” var=”<string>” scope=”<string>”>
…
</c:if>
属性
if 标签有如下属性:
属性
形容
是否必要
默认值
test
条件
是
无
var
用于存储条件后果的变量(限域变量名)
否
无
scope
var 属性的作用域 可取值:page|request|session|application
否
page
示例
<%
request.setAttribute("flag",true);
request.setAttribute("num",1);
%>
<c:if test=”${flag}”>
<p> 后果为 true<p>
</c:if>
<c:if test=”${num > 0}”>
<p>num 的值比 0 大 <p>
</c:if>
注:JSTL 中没有 else 标签,为了模仿 else 的情景,须要应用两个 if 标签,并且这两个标签为 相同 的条件。
choose、when 和 otherwise 标签
choose 和 when 标签的作用与 Java 中的 switch 和 case 关键字类似,用于在泛滥选项中做出抉择。也就是说:他们为互相排挤的条件式执行提供相干内容。
switch 语句中有 case,而 choose 标签中对应有 when,switch 语句中有 default,而 choose 标签中有 otherwise。
语法格局
<c:choose>
<c:when test="<boolean>">
...
</c:when>
<c:when test="<boolean>">
...
</c:when>
...
...
<c:otherwise>
...
</c:otherwise>
</c:choose>
属性
- choose 标签没有属性。
- when 标签只有一个 test 属性。
- otherwise 标签没有属性。
示例
<%
request.setAttribute("score", 90);
%>
<c:choose>
<c:when test="${score < 60}">
<h3> 你个小渣渣!</h3>
</c:when>
<c:when test="${score >= 60 && score < 80}">
<h3> 反动尚未胜利,同志仍需致力!</h3>
</c:when>
<c:otherwise>
<h3> 你很棒棒哦!</h3>
</c:otherwise>
</c:choose>
留神点
- choose 标签和 otherwise 标签没有属性,而 when 标签必须设置 test 属性
- choose 标签中必须有至多一个 when 标签,能够没有 otherwise 标签
- otherwise 标签必须放在最初一个 when 标签之后
- choose 标签中只能有 when 标签和 otherwise 标签,when 标签和 otherwise 标签能够嵌套其余标签
- otherwise 标签在所有的 when 标签不执行的状况下才会执行
迭代标签
forEach 是将一个主体内容迭代屡次,或者迭代一个对象汇合。能够迭代的对象包含所有的 java.util.Collection 和 java.util.Map 接口的实现,以及对象或者根本类型的数组。他还可 以迭代 java.util.Iterator 和 java.util.Enumeration, 但不能在多个动作指令中应用 Iterator 或者 Enumeration, 因为 Iterator 或者 Enumeration 都不能重置(reset)。各属性含意如下:
forEach 标签
语法格局
<c:forEach
items="<object>"
begin="<int>"
end="<int>"
step="<int>"
var="<string>"
varStatus="<string>">
</c:forEach>
属性
属性
形容
是否必要
默认值
items
要被循环的数据
否
无
begin
开始的元素(0= 第一个元素,1= 第二个元素)
否
0
end
最初一个元素(0= 第一个元素,1= 第二个元素)
否
Last element
step
每一次迭代的步长
否
1
var
代表以后条目标变量名称
否
无
varStatus
代表循环状态的变量名称
否
无
forEach varStatus 属性
- index: 以后这次迭代从 0 开始的迭代索引
- count: 以后这次迭代从 1 开始的迭代计数
- first: 用来表明以后这轮迭代是否为第一次迭代的标记
- last: 用来表明以后这轮迭代是否为最初一次迭代的标记
示例
1. 遍历主体内容屡次
<c:forEach begin=” 开始数 ” end=” 完结数 ” step=” 迭代数 ” var=” 限域变量名 ”>
</c:forEach>
相当于 java 的 for 循环:
for(int i = 0; i < 10; i++) {
}
如下:
<!– 遍历主体内容屡次 –>
<c:forEach begin=”0″ end=”10″ var=”i” >
题目 ${i}<br>
</c:forEach>
2. 循环
<c:forEach items=” 被循环的汇合 ” var=” 限域变量名 ” varStatus=” 以后成员对象的相干信息 ”>
</c:forEach>
相当于 java 的 foreach 循环:
for(String str : list) {
}
如下:
<%
List<String> list = new ArrayList<String>();
for (int i = 1; i <= 10; i++) {list.add("A:" + i);
}
pageContext.setAttribute("li", list);
%>
<!– 循环汇合 –>
<c:forEach items=”${li}” var=”item”>
${item}
</c:forEach>
名称 | 以后成员下标 | 以后成员循环数 | 是否第一次被循环 | 是否最初一次被循环 |
---|---|---|---|---|
${item} | ${itemp.index} | ${itemp.count} | ${itemp.first} | ${itemp.last} |
<!– 循环对象汇合 –>
<%
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>
<button> 删除 </button>
</td>
</tr>
</c:forEach>
</table>
</c:if>
<!– 遍历 Map –>
<%
Map<String,Object> map = new HashMap<String,Object>();
map.put("map1", "aaa");
map.put("map2", "bbb");
map.put("map3", "ccc");
pageContext.setAttribute("map", map);
%>
<c:forEach items=”${map}” var=”mymap”>
键:${mymap.key}- 值:${mymap.value} <br>
</c:forEach>
格式化动作标签
JSTL 提供了格式化和解析数字和日期的标签, 咱们探讨外面有:formatNumber、formatDate、parseNumber 及 parseDate。
formatNumber 标签
formatNumber 标签用于格式化数字,百分比,货币。该标签用指定的格局或精度来格式化数字。(将数值型数据转换成指定格局的字符串类型。)
语法格局
<fmt:formatNumber
value=”<string>”
type=”<string>”
var=”<string>”
scope=”<string>”/>
属性
属性
形容
是否必要
默认值
value
要显示的数字
是
无
type
NUMBER,CURRENCY,或 PERCENT 类型
否
Number
var
存储格式化数字的变量
否
Print to page
scope
var 属性的作用域
否
page
留神:
- 如果设置了 var 属性,则格式化后的后果不会输入,须要通过 el 表达式获取 var 对应的限域变量名
- 默认的类型(type)的取值为 number。可取值:number 数值型、percent 百分比类型、currency 货币型
示例
<fmt:formatNumber value=”10″ type=”number” var=”num” /> ${num}
<fmt:formatNumber value=”10″ type=”percent” />
<fmt:formatNumber value=”10″ type=”currency” />
<!– 设置时区 –>
<fmt:setLocale value=”en_US”/>
<fmt:formatNumber value=”10″ type=”currency” />
formatDate 标签
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
否
date
dateStyle
FULL, LONG, MEDIUM, SHORT, 或 DEFAULT
否
default
timeStyle
FULL, LONG, MEDIUM, SHORT, 或 DEFAULT
否
default
pattern
自定义格局模式
否
无
timeZone
显示日期的时区
否
默认时区
var
存储格式化日期的变量名
否
显示在页面
scope
存储格式化日志变量的范畴
否
页面
标签格局模式
代码
形容
实例
y
不蕴含纪元的年份。如果不蕴含纪元的年份小于 10,则显示不具备前导零的年份。
2002
M
月份数字。一位数的月份没有前导零。
April & 04
d
月中的某一天。一位数的日期没有前导零。
20
h
12 小时制的小时。一位数的小时数没有前导零。
12
H
24 小时制的小时。一位数的小时数没有前导零。
0
m
分钟。一位数的分钟数没有前导零。
45
s
秒。一位数的秒数没有前导零。
52
示例
<%
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” dateStyle=”long”/><br/>
<fmt:formatDate value=”${myDate}” type=”both” dateStyle=”short”/><br/>
<fmt:formatDate value=”${myDate}” type=”both” timeStyle=”full”/><br/>
<fmt:formatDate value=”${myDate}” type=”both” timeStyle=”long”/><br/>
<fmt:formatDate value=”${myDate}” pattern=”HH:mm yyyy/MM/dd”/><br/>
parseNumber 标签
parseNumber 标签用来解析数字,百分数,货币。(parseNumber 标签能够将数字、货币或百分比类型的字符串转换成数值型。)
语法格局
<fmt:parseNumber
value=”<string>”
type=”<string>”
var=”<string>”
scope=”<string>”/>
属性
属性
形容
是否必要
默认值
value
要解析的数字
否
Body
type
NUMBER,,CURRENCY,或 PERCENT
否
number
var
存储待解析数字的变量
否
Print to page
scope
var 属性的作用域
否
page
示例
<fmt:parseNumber value=”100″ />
<fmt:parseNumber value=”100″ type=”number” />
<fmt:parseNumber value=”100%” type=”percent” />
<fmt:parseNumber value=”¥10.00″ type=”currency” />
parseDate 标签
parseDate 标签用于解析日期。(将指定格局的字符串转换成 Date 类型。)
语法格局
<fmt:parseDate
value=”<string>”
type=”<string>”
dateStyle=”<string>”
timeStyle=”<string>”
pattern=”<string>”
var=”<string>”
scope=”<string>”/>
属性
属性
形容
是否必要
默认值
value
要显示的日期
是
无
type
DATE, TIME, 或 BOTH
否
date
dateStyle
FULL, LONG, MEDIUM, SHORT, 或 DEFAULT
否
default
timeStyle
FULL, LONG, MEDIUM, SHORT, 或 DEFAULT
否
default
pattern
自定义格局模式
否
无
var
存储格式化日期的变量名
否
显示在页面
scope
存储格式化日志变量的范畴
否
页面
示例
<fmt:parseDate value=”2020-01-06″ type=”date” />
<fmt:parseDate value=”2020/01/06″ pattern=”yyyy/MM/dd” />