淘先锋技术网

首页 1 2 3 4 5 6 7

系列文章目录

还搞不懂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指令常用两大功能

  1. 声明文件为JSP页面
    指明与JSP Container 的沟通方式
    通常只需要按如下方式声明
    <%@page pageEncoding="UTF-8" %>
  2. 引入第三方包
    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隐式对象对应类型
outjavax.servlet.jsp.JspWriter
requestjavax.servlet.http.HttpServletRequest
responsejavax.servlet.http.HttpServletResponse
pageContextjavax.servlet.jsp.PageContext
sessionjavax.servlet.http.HttpSession
applicationjavax.servlet.ServletContext
pagejava.lang.Object
configjavax.servlet.ServletConfig
exceptionjava.lang.Throwable

7. JSP四大作用域

作用域名称描述对应的隐式对象所属类型
application在当前整个应用中有效applicationServletContext
session在当前会话中有效sessionHttpSession
request在当前请求中有效requestHttpServletRequest
page在当前页面有效pageContextPageContext

示例:

<%
	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)

架构图1

JSP仅负责数据的显示,由Servlet负责业务流程的控制。

  • 优点:
    代码重用性高,程序可扩展性好,维护容易。适用于大型项目的开发
  • 缺点
    增加了应用开发的复杂程度。
  • JavaEE设计模式:ModelViewController(MVC)

3. Servlet和JSP之间的通信

  • 从JSP转到Servlet
  1. 用表单提交到Servlet
  2. Servlet可以获取请求参数数据:request.getParameter(“参数名”);
  3. 用< jsp:forward >将请求信息自动传递到Servlet
  4. 传递的数据可以设置到请求域中传递。
  5. 通过代码片段:response.sendRedirect(String uri)
    无法使用请求域传递数据。
  • 从Servlet转到JSP
  1. 使用RequestDispatcher接口的forward(request, response)方法
  2. 要传递的数据可以设置到请求域中传递
  3. 通过response.sendRedirect(String uri)
  4. 无法使用请求域传递数据。

Servlet和JSP之间经常是通过request来传递数据

四、EL表达式

EL(Expression Language)为表达式语言,JSP2.0规范中的一部分。

  • EL提供了一些标识符、存取器和运算符,用来获取驻留在web容器中的数据。
  • EL的语法: ${EL Expression}
  • EL可用于JSP页面中所有HTML和JSP标签中。

1. EL有效表达式的组成元素

  1. 文字常量值:表示固定值 ——数字、字符串、布尔型或空值。
  2. 运算符:允许对数据和文字进行组合以及比较。
  3. 变量:用来引用存储在数据中心中的数据对象。
  4. 存取器:用来检索对象的属性值或集合中的元素。
  5. 函数调用:调用特定的函数来完成相应的功能。

EL中的文字

文字常量被指定为固定值,主要包括:

  • 数字:整数、浮点数
  • 字符串:任何由单引号或双引号限定的字符串
  • 布尔型:true、false
  • 空值:null -> 输出时会转换成空串显示

EL运算符

在这里插入图片描述

EL中的变量

EL中有11个隐式对象变量,这些变量可以直接用来访问特定的数据。

在EL中与隐式对象变量无关联的变量被认为是存储在四个JSP作用域(page, request, session,application)中的对象。

作用域中对象的默认搜索顺序是page、request、session、application。

类别标识符描述
JSPpageContextPageContext实例对应于当前页面的处理
请求参数param按名称存储请求参数的主要值的Map类
paramValues将请求参数的所有值作为String数组存储的Map类
作用域pageScope与页面作用域属性的名称和值相关联的Map类
requestScope与请求作用域属性的名称和值相关联的Map类
sessionScope与会话作用域属性的名称和值相关联的Map类
applicationScope与应用程序作用域属性的名称和值相关联的Map类
请求头header按名称存储请求头主要值的Map类
headerValues将请求头的所有值作为String数组存储的Map类
Cookiecookie按名称存储请求附带的cookie的Map类用value去cookie对象的值
初始化参数initParam按名称存储Web应用上下文初始化参数的Map类

EL中的存取器

EL提供了两种不同的存取器来存取对象的属性值或集合中的元素。

  • 点运算符: .用于获取对象变量的属性值
  • 方括号运算符:[] 用于获取数组或集合中的指定元素,内部变量名用 ‘’ 包裹。

EL中的保留字

在程序中不要使用EL的保留字作为变量名或方法的名称,否则无法用EL来存取。

运算符描述运算符描述
andge大于等于
ortrue
notfalse
eq等于nullNull
ne不等于empty判断空值
le小于等于div相除
gt大于mod取模

五、JSTL标签

JSP Standard Tag Library:JSP标准标签库是一个实现Web应用程序中常见通用功能的定制标签库集。

通过为表示层任务(如数据格式化和迭代或条件内容)提供标准实现,JSTL 使 JSP程序员可以专注于特定于应用程序的开发需求。

1. JSTL的分类

标签库URI前缀备注
Corehttp://java.sun.com/jsp/jstl/corec核心标签库:包含Web应用的常用功能,比如:逻辑判断、循环、表达式赋值、基本输入输出等。
I18Nhttp://java.sun.com/jsp/jstl/fmtfmt国际化和格式化标签库:用来格式化显示数据的工作,比如:对不同区域的日期格式化等
Databasehttp://java.sun.com/jsp/jstl/sqlsql数据库标签库:完成访问数据库的工作
XMLhttp://java.sun.com/jsp/jstl/xmlxXML标签库:用来访问XML文件的工作,这是JSTL标签库的一个特点
Functionshttp://java.sun.com/jsp/jstl/functionsfnEL函数标签库:用来调用已定义的函数

此处只描述常用标签库及其常用功能
使用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则相反Yboolean
var用来储存test运算后的结果,即true或falseString
scopevar变量的JSP范围NStringpage

迭代标签< c:forEach >

语法:

<c:forEach [var="varName"] [items="collection"]
	[varStatus="varStatusName"]
	[begin="begin"] [end="end"] [step="step"]>
	主体内容
	</c:forEach>

属性说明:

名称说明EL类型必须默认值
var用来存放现在指到的成员NString
items被迭代的集合对象YArrays Collection,Iterator,Enumeration,Map,String
varStatus用来存放现在指到的相关成员信息NString
begin开始的位置Yint
end结束的位置Yint最后一个成员
step每次迭代的间隔数Yint

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个字符,后面跟…