系列文章目录
还搞不懂jsp和servlet的区别,别怕,本文将带领你走入jsp的世界,领略曾经火遍一时的jsp的鲜花如何开满编程的世界的。
前言
JSP(JavaServer Pages)是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准,其网址为http://www.javasoft.com/products/jsp。
该技术为创建显示动态生成内容的Web页面提供了一个简捷而快速的方法。JSP技术的设计目的是使得构造基于Web的应用程序更加容易和快捷,而这些应用程序能够与各种Web服务器,应用服务器,浏览器和开发工具共同工作。
JSP规范是Web服务器、应用服务器、交易系统、以及开发工具供应商间广泛合作的结果。在传统的网页HTML文件(htm,.html)中加入 Java程序片段(Scriptlet)和JSP标记(tag),就构成了JSP网页(*.jsp)。
Web服务器在遇到访问JSP网页的请求时,首先执行其中的程序片段,然后将执行结果以HTML格式返回给客户。
程序片段可以操作数据库、重新定向网页以及发送 email 等等,这就是建立动态网站所需要的功能。
所有程序操作都在服务器端执行,网络上传送给客户端的仅是得到的结果,对客户浏览器的要求最低,可以实现无 Plugin,无ActiveX,无Java Applet,甚至无Frame。
一、简述
1. JSP
Java Server Pages:Java服务器页面,一种动态网页技术标准。
- 扩展名为“.jsp”
- 放置在Web应用根目录下
- 在传统的网页HTML文件(.htm,.html)中加入JSP代码(Java程序片段和JSP标记),就构成了JSP页面
- HTML用于展示页面内容,而JSP代码用于访问动态内容
<%@pagepageEncoding=“UTF-8”%>
<html>
<head>
<title>Jsp技术</title>
</head>
<body bgcolor="#ffffff">
<% java.util.Datenow=newjava.util.Date();
out.println("当前时间是:"+now);
%>
<h1>你好,第一个JSP页面</h1>
</body>
</html>
Servlet是Java代码中输出HTML,JSP是HTML中嵌入Java代码。
2. JSP 执行过程
JSP实质上就是Servlet
- Eclipse-JEE在运行web项目时,会把JSP转译生成的java文件存放在如下目录中
工作空间.metadata.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost - Idea在运行Web项目时,会把JSP转译生成的java文件存放在如下目录中
用户空间.IntelliJIdea2019.2\system\tomcat\Unnamed_my_project_3\work\Catalina\localhost
3. JSP优点
- 优良的性能:优于CGI,ASP,PHP
- 平台无关性:操作系统无关,Web服务器无关
- 可扩展性:tag的扩展机制,简化页面开发
4. JSP页面的构成
- 传统语法
静态内容:HTML标签、CSS、JS代码
Expression (表达式)
Scriptlet (代码片段)
Declaration (声明)
Comment (注释)
Directives (指令)
Action (动作)
Inner Object (内置对象,隐式对象) - EL
标签:自定义标签和JSTL
二、JSP常用模块说明
1. JSP注释
语法格式:
<%--这是JSP注释,但客户端不能查看到--%>
- JSP注释在转译阶段就被忽略了。
如果要把JSP的代码注释掉,就一定要用JSP注释。 - 区别于HTML注释
<!-- 这是HTML注释,但客户端可以查看到 -->
2. JSP表达式
语法格式:
<%=Java表达式 %>
=后面必须是字符串变量或可以被转换成字符串的表达式
使用:表达式是对数据的表示,会计算它的结果并进行显示
转译时:表达式里的代码总是被直接当作out.print()的参数,把表达式的值向响应输出流中输出。
所以末尾千万不能加分号
<body>
<h1>JSP表达式</h1>
<b>PI 的值:</b><%=Math.PI %><br/>
<b>100,99中最大的值 :</b><%=Math.max(100,99) %>
<br/><b>100,99中最小的值 :</b><%=Math.min(100,99) %><br/>
<b>3+2-5的值 :</b><%=3+2-5 %><br/>
<b>(3+2)==5的值 :</b><%=(3+2)==5 %><br/>
<b>(3+2)!=5的值 :</b><%=(3+2)!=5 %><br/>
</body>
3. JSP代码片段
语法格式:
<% Java代码区 %>
作用:JSP Scriptlet就是在JSP页面里嵌入一段Java代码,所以Scriptlet也叫代码片段。
转译时:代码片段里的代码总是被放置在服务方法中。
所以Scriptlet中声明的变量总是局部变量不能在代码片段中定义方法
<body>
<h1>以直角三角形的形式显示数字</h1>
<% for(inti=1;i<10;i++) {
for(intj=1;j<=i; j++) {
out.println(j);
}
out.println("<br/>");
}
%>
</body>
4. JSP指令
page指令
page指令常用两大功能
- 声明文件为JSP页面
指明与JSP Container 的沟通方式
通常只需要按如下方式声明
<%@page pageEncoding="UTF-8" %>
- 引入第三方包
JSP中使用到其他包中的类,则需要引入,但一般IDE工具会自动引入,使用如下格式
<%@page import="java.util.List" %>
taglib指令
taglib指令可以让JSP页面使用自定义标签
taglib 指令的作用是在JSP页面中,将标签库描述符文件引入到该页面中,并设置前缀,利用标签的前缀去使用标签库表述文件中的标签
语法:
<%@tagliburi="标签库描述符文件"prefix="前缀名"%>
示例:<%@ taglib uri =“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
5. JSP 动作(Action)
< jsp:include> 和< jsp:param>
- jsp:include
用于动态包含JSP页面或HTML文件等在执行期间才把目标页面的内容包含到当前页面中。
格式:
<!--不含参数-->
<jsp:include page="URLSpec" flush="true"/>
<!--含参数-->
<jsp:include page="URLSpec" flush="true">
<jsp:param name="ParamName" value="paramValue"/>
</jsp:include>
- jsp:param
用来设定include文件时的参数和对应的值
动态包含的文件和被包含文件用的是同一个request对象
< jsp:forward >
用于将一个jsp的内容传送到page所指定的JSP程序或者Servlet中处理(URL)
格式:
<jsp:forward page=“urlSpec”/>
<jsp:forward page=“urlSpec”>
<jsp:param name=“paramName” value=“paramValue”/>
</jsp:forward>
< jsp:param>用于指定参数和其对应的值
< jsp:forward>的实质就是请求分派
6. JSP九大隐式对象
JSP隐式对象 | 对应类型 |
---|---|
out | javax.servlet.jsp.JspWriter |
request | javax.servlet.http.HttpServletRequest |
response | javax.servlet.http.HttpServletResponse |
pageContex | tjavax.servlet.jsp.PageContext |
session | javax.servlet.http.HttpSession |
application | javax.servlet.ServletContext |
page | java.lang.Object |
config | javax.servlet.ServletConfig |
exception | java.lang.Throwable |
7. JSP四大作用域
作用域名称 | 描述 | 对应的隐式对象 | 所属类型 |
---|---|---|---|
application | 在当前整个应用中有效 | application | ServletContext |
session | 在当前会话中有效 | session | HttpSession |
request | 在当前请求中有效 | request | HttpServletRequest |
page | 在当前页面有效 | pageContext | PageContext |
示例:
<%
if (pageContext.getAttribute("pageCount")==null) {
pageContext.setAttribute("pageCount", newInteger(0));
}
if (request.getAttribute("requestCount")==null) {
request.setAttribute("requestCount", newInteger(0));
}
if (session.getAttribute("sessionCount")==null) {
session.setAttribute("sessionCount",newInteger(0));
}
if (application.getAttribute("appCount")==null) {
application.setAttribute("appCount",newInteger(0));
}
%>
<h2>reqeust、session、application 和 pageContext作用域</h2>
<%
Integer count= (Integer)pageContext.getAttribute("pageCount");
pageContext.setAttribute("pageCount", new Integer(count.intValue()+1));
Integer count2= (Integer)request.getAttribute("requestCount");
request.setAttribute("requestCount", new Integer(count2.intValue()+1));
Integer count3= (Integer)session.getAttribute("sessionCount");
session.setAttribute("sessionCount",new Integer(count3.intValue()+1));
Integer count4= (Integer)application.getAttribute("appCount");
application.setAttribute("appCount",new Integer(count4.intValue()+1));
%>
页面作用域计数:<%=pageContext.getAttribute("pageCount")%><br/>
请求作用域计数:<%=request.getAttribute("requestCount")%><br/>
会话作用域计数:<%=session.getAttribute("sessionCount")%><br/>
应用作用域程序计数: <%=application.getAttribute("appCount")%><br/>
三、JSP应用开发模式
1. Model1 体系结构(JSP + JavaBean)
JSP负责数据的显示和业务流程的控制。
- 优点:
适用于快速开发小规模项目。 - 缺点
代码重用性低,程序可扩展性差,增加了应用的维护难度。
2. Model2体系结构(JSP + Servlet + JavaBean)
JSP仅负责数据的显示,由Servlet负责业务流程的控制。
- 优点:
代码重用性高,程序可扩展性好,维护容易。适用于大型项目的开发 - 缺点
增加了应用开发的复杂程度。 - JavaEE设计模式:ModelViewController(MVC)
3. Servlet和JSP之间的通信
- 从JSP转到Servlet
- 用表单提交到Servlet
- Servlet可以获取请求参数数据:request.getParameter(“参数名”);
- 用< jsp:forward >将请求信息自动传递到Servlet
- 传递的数据可以设置到请求域中传递。
- 通过代码片段:response.sendRedirect(String uri)
无法使用请求域传递数据。
- 从Servlet转到JSP
- 使用RequestDispatcher接口的forward(request, response)方法
- 要传递的数据可以设置到请求域中传递
- 通过response.sendRedirect(String uri)
- 无法使用请求域传递数据。
Servlet和JSP之间经常是通过request来传递数据
四、EL表达式
EL(Expression Language)为表达式语言,JSP2.0规范中的一部分。
- EL提供了一些标识符、存取器和运算符,用来获取驻留在web容器中的数据。
- EL的语法: ${EL Expression}
- EL可用于JSP页面中所有HTML和JSP标签中。
1. EL有效表达式的组成元素
- 文字常量值:表示固定值 ——数字、字符串、布尔型或空值。
- 运算符:允许对数据和文字进行组合以及比较。
- 变量:用来引用存储在数据中心中的数据对象。
- 存取器:用来检索对象的属性值或集合中的元素。
- 函数调用:调用特定的函数来完成相应的功能。
EL中的文字
文字常量被指定为固定值,主要包括:
- 数字:整数、浮点数
- 字符串:任何由单引号或双引号限定的字符串
- 布尔型:true、false
- 空值:null -> 输出时会转换成空串显示
EL运算符
EL中的变量
EL中有11个隐式对象变量,这些变量可以直接用来访问特定的数据。
在EL中与隐式对象变量无关联的变量被认为是存储在四个JSP作用域(page, request, session,application)中的对象。
作用域中对象的默认搜索顺序是page、request、session、application。
类别 | 标识符 | 描述 |
---|---|---|
JSP | pageContext | PageContext实例对应于当前页面的处理 |
请求参数 | param | 按名称存储请求参数的主要值的Map类 |
paramValues | 将请求参数的所有值作为String数组存储的Map类 | |
作用域 | pageScope | 与页面作用域属性的名称和值相关联的Map类 |
requestScope | 与请求作用域属性的名称和值相关联的Map类 | |
sessionScope | 与会话作用域属性的名称和值相关联的Map类 | |
applicationScope | 与应用程序作用域属性的名称和值相关联的Map类 | |
请求头 | header | 按名称存储请求头主要值的Map类 |
headerValues | 将请求头的所有值作为String数组存储的Map类 | |
Cookie | cookie | 按名称存储请求附带的cookie的Map类用value去cookie对象的值 |
初始化参数 | initParam | 按名称存储Web应用上下文初始化参数的Map类 |
EL中的存取器
EL提供了两种不同的存取器来存取对象的属性值或集合中的元素。
- 点运算符: .用于获取对象变量的属性值
- 方括号运算符:[] 用于获取数组或集合中的指定元素,内部变量名用 ‘’ 包裹。
EL中的保留字
在程序中不要使用EL的保留字作为变量名或方法的名称,否则无法用EL来存取。
运算符 | 描述 | 运算符 | 描述 |
---|---|---|---|
and | 与 | ge | 大于等于 |
or | 或 | true | 真 |
not | 非 | false | 假 |
eq | 等于 | null | Null |
ne | 不等于 | empty | 判断空值 |
le | 小于等于 | div | 相除 |
gt | 大于 | mod | 取模 |
五、JSTL标签
JSP Standard Tag Library:JSP标准标签库是一个实现Web应用程序中常见通用功能的定制标签库集。
通过为表示层任务(如数据格式化和迭代或条件内容)提供标准实现,JSTL 使 JSP程序员可以专注于特定于应用程序的开发需求。
1. JSTL的分类
标签库 | URI | 前缀 | 备注 |
---|---|---|---|
Core | http://java.sun.com/jsp/jstl/core | c | 核心标签库:包含Web应用的常用功能,比如:逻辑判断、循环、表达式赋值、基本输入输出等。 |
I18N | http://java.sun.com/jsp/jstl/fmt | fmt | 国际化和格式化标签库:用来格式化显示数据的工作,比如:对不同区域的日期格式化等 |
Database | http://java.sun.com/jsp/jstl/sql | sql | 数据库标签库:完成访问数据库的工作 |
XML | http://java.sun.com/jsp/jstl/xml | x | XML标签库:用来访问XML文件的工作,这是JSTL标签库的一个特点 |
Functions | http://java.sun.com/jsp/jstl/functions | fn | EL函数标签库:用来调用已定义的函数 |
此处只描述常用标签库及其常用功能
使用JSTL功能需要引入相应的包,此处使用jstl-1.2.jar
2. 核心标签库
条件标签 < c:if >
用于简单的条件语句。
语法:
<c:if test="需要判断的条件表达式"
var="用来保存判断后的结果(true或false)的变量名"
scope="page|request|session|application">
主体内容
</c:if>
属性说明:
名称 | 说明 | EL | 类型 | 必须 | 默认值 |
---|---|---|---|---|---|
test | 如果表达式结果为true,则执行本体内容,false则相反 | Y | boolean | 是 | 无 |
var | 用来储存test运算后的结果,即true或false | N | String | 否 | 无 |
scope | var变量的JSP范围 | N | String | 否 | page |
迭代标签< c:forEach >
语法:
<c:forEach [var="varName"] [items="collection"]
[varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
主体内容
</c:forEach>
属性说明:
名称 | 说明 | EL | 类型 | 必须 | 默认值 |
---|---|---|---|---|---|
var | 用来存放现在指到的成员 | N | String | 否 | 无 |
items | 被迭代的集合对象 | Y | Arrays Collection,Iterator,Enumeration,Map,String | 否 | 无 |
varStatus | 用来存放现在指到的相关成员信息 | N | String | 否 | 无 |
begin | 开始的位置 | Y | int | 否 | 0 |
end | 结束的位置 | Y | int | 否 | 最后一个成员 |
step | 每次迭代的间隔数 | Y | int | 否 | 1 |
varStatus属性的说明:
varStatus为迭代状态指定范围变量的名称,此变量是javax.servlet.jsp.jstl.core.LoopTagStatus类的实例。它有四个属性:
- index 表示当前这次迭代从0开始的迭代索引。
- count 表示当前这次迭代从1开始的迭代计数。
- first 表示当前这次迭代到的成员是否为第一个。
- last 表示当前这次迭代到的成员是否为最后一个
<h3> c:forEach 使用</h3>
<%
String atts[] =new String[5];
atts[0]="hello";
atts[1]="this";
atts[2]="is";
request.setAttribute("atts", atts);
%>
<!-- 遍历List-->
<c:forEach items="${atts}" var="item" var Status="s">
${s.count} <c:out value="${item}"/><br/>
</c:forEach>
<!-- 遍历map-->
<c:forEach items="${map}" var="entry">
${entry.key}-${entry.value}<br/>
</c:forEach>
3. 国际化标签库
日期格式化标签< fmt:formatDate >
格式化日期时间,属性有
- value:要格式化的日期时间对象,不能是字符串
- type:格式化的类型,可选值:date、time和both
- dateStyle:日期样式,可选值:default、short、medium、long、full
- timeStyle:时间样式,可选值:default、short、medium、long、full
- pattern:格式化的模式串
- var:变量名
- scope:变量的存储范围
示例:
<fmt:formatDate value="${cDate}" type="both"/>
<fmt:formatDate value="${cDate}" pattern="yyyy-MM-dd HH:mm:ss"/>
数字格式化标签< fmt:formatNumber >
用于格式化数字。属性有
- value:要格式化的数字,该数值可以是String类型或Number类型的实例
- type:格式化的类型,可选值:number、currency和percent
- pattern:格式化的模式串
- var:变量名
- scope:存储范围
- maxIntegerDigits:指定整数部分的最大位数
- minIntegerDigits:指定整数部分的最小位数
- maxFractionDigits:指定小数部分的最大位数
- minFractionDigits:指定小数部分的最小位数
示例:
<fmt:formatNumber value="1000.88" type="currency" var="money"/>
<fmt:formatNumber value="1000.88" pattern="¥#,###.00"/>
4. 函数标签库
函数标签库需要在EL表达式中使用
函数签名 | 描述 |
---|---|
fn:contains(string, substring) | 如果参数string中包含参数substring,返回true |
fn:containsIgnoreCase(string,substring) | 如果参数string中包含参数substring(忽略大小写),返回true |
fn:endsWith(string, suffix) | 如果参数string以参数suffix结尾,返回true |
fn:escapeXml(string) | 将有特殊意义的XML (和HTML)转换为对应的XML characterentity code,并返回 |
fn:indexOf(string, substring) | 返回参数substring在参数string中第一次出现的位置 |
fn:join(array, separator) | 将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。 |
fn:length(item) | 返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。 |
fn:replace(string, before,after) | 返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果 |
fn:split(string, separator) | 返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素 |
fn:startsWith(string, prefix) | 如果参数string以参数prefix开头,返回true |
fn:substring(string, begin,end) | 返回参数string部分字符串, 从参数begin开始到参数end位置,不包括end位置的字符 |
fn:substringAfter(string,substring) | 返回参数substring在参数string中后面的那一部分字符串 |
fn:substringBefore(string,substring) | 返回参数substring在参数string中前面的那一部分字符串 |
fn:toLowerCase(string) | 将参数string所有的字符变为小写,并将其返回 |
fn:toUpperCase(string) | 将参数string所有的字符变为大写,并将其返回 |
fn:trim(string) | 去除参数string 首尾的空格,并将其返回 |
示例:如果新闻标题字符超过20个,就显示前面20个字符,后面跟…