JSP(Java Script Pages)技术是一种网站开发技术,可以让Web开发人员快速、高效的开发出易于维护的动态网页。使用JSP技术开发的Web应用程序具有跨平台性,不需要修改程序,发布后即可在Windows、Linux等不同的操作系统中运行。
10.1 JSP技术概述
JSP是一种基于Java语言开发的动态网页技术,它可以将网页的静态和动态部分分离。静态部分的书写可以采用HTML语言以往的方式,而动态部分用特殊标记嵌入,标记以 <% 开始,以 %> 结束
<html><head><title>JSP演示程序</title></head><body></body></html>
JSP文件的扩展名为“.jsp”,可以放置在任何一个放置 WEB页面的目录下。JSP文件看起来与HTML文件很相似,但与Servlet文件差别很大
10.2 JSP运行环境搭建
JSP需要JSP引擎的支持才能运行。JSP引擎是指能够运行JSP的Web服务软件。安装了JSP引擎的计算机就是JSP的Web服务器。Tomcat是一个常见的Web服务器。
10.2.1 安装
略
10.2.2 测试
bin目录下的tomcat8.exe运行
测试成功
10.2.3 第一个JSP程序
【实例1】创建一个JSP文件,并通过浏览器访问。
1.在Tomcat安装目录 webapps下创建一个新的文件夹myapp
2.在文件夹myapp下再创建一个WEB-INF文件夹
3.在WEB-INF文件夹下再创建一个文件web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app><display-name>My web Application</display-name><description>A Application for test</description>
</web-app>
4.在ROOT目录下,创建一个文件index.jsp
<html><body><center>System now time is : <%=new java.util.Date()%></center></body></html>
5.启动Tomcat
说明
web.xml是一个样式配置文件。index.jsp是一个JSP文件。使用java.util.Date()获取当前系统时间,并在网页中心展示。
10.3 基本语法
JSP页面包含静态和动态内容。静态JSP基本上是HTML脚本。动态内容包括JSP指令、JSP表达式、Scriptlet(脚本集)、声明、动作、注释等、
10.3.1 HTML注释
HTML注释是在客户端的源代码中显示的注释。
<!-- -->
注释正常情况下在页面上是看不到的。除非访问源代码。
理论上注释里可以存放任意合法的表达式
10.3.2 隐藏注释
隐藏注释也可以说是真正的JSP注释。因为只显示在JSP代码中,不会发送给客户端,也不可以通过“访问源代码”的形式进行查看。
<%-- --%>
在这里面的语句不会进行编译,也不会再客户端浏览器和客户端的HTML源代码中进行展示。
10.3.3 声明
类似于Java语言中的变量定义,在使用变量和方法之前必须先声明,否则会报错。
JSP文件必须声明将来在程序中使用的变量和方法。
语法格式:
<%! declaration; {declaration; } ... % >
下面给出了一个声明的简单例子:
<%! char sex = 'm' ; %>
<%! double d,e,f ;%>
<%! Object o = new Object();%>
一次可以声明多个变量,他们之间需要以",“分隔,并以” ; "结尾。
- 声明必须以" ; "结尾。
- 可以直接使用由 <% @page %>包含的变量,无需重新生命
-声明的有效范围是这个页面的内部。如果多个页面需要同样的声明,则可以将这些声明写成一个文件。然后使用<% @include % >
或< jsp:include >
来包含这个文件
10.3.4 表达式
程序中的表达式类似数学中的公式。可以通过计算来获得所需要的值。
表达式用来在JSP页面上输出结果。分别使用<%= 和 %>
作为开始和结束的标志
语法格式:
<%= expression % >
下面给出了一个声明的简单例子:
<%= person.getName()%>
<b><%= new Date() %></b>
表达式实现将获得的用户名自动转换为字符串类型,然后插入表达式所在的JSP文件的位置。
10.3.5 脚本集(Scriptlet)
脚本集(Scriptlet)是指在JSP中包含的一段有效的Java代码。类似于在开发游戏的时候为某游戏场景写的一段运行脚本。
语法格式
<% code fragment %>
下面给出了一个脚本集的的简单例子:
<%@ page language = "java" >
<html><head><title>Scriptlet example</title></head><body><%request.setAttribute("name","aaa"); //设置request的参数namesession.setAttribute("name","java自学手册"); //设置session的参数nameapplication.setAttribute("name","Java语言"); //设置application的参数name%><%if(request.getParameter("name") != null )out.println(request.getParameter("name"));if(session.getParameter("name")!=null)out.println(request.getParameter("name"));if(application.getParameter("name")!=null)out.println(request.getParameter("name"));%></body>
</html>
在JSP页面中,可以将Java代码放在<% %>之间。
一个Scriptlet代码块可以包含多个JSP语句,表达式和方法等
10.4 JSP指令元素
JSP指令向JSP引擎提供编译信息。
通常JSP指令在当前页面内有效,并不向客户端产生任何输出。
常见的JSP指令包括:include 、 page 、 taglib 等
通用语法格式为:<%@ 指令标记 ["属性1" = "值1" "属性1" ="值2"] %>
【实例1】使用include指令加载hello.txt文件,并在浏览器中展示文件的内容。
10.4.1 include 指令
include指令是文件加载指令。用于在当前文件中包含指定位置的资源文件内容。被添加的内容可以被解析并进行显示。include指令的语法格式:
<%@ include file = "relativeURL" %>
参数relativeURL是要包含的文件。
10.4.2 page 指令
page指令即页面指令。用来描述JSP文件的全局属性,页面指令的属性将影响到该JSP页面。同一个JSP页面可以包含多个页面指令。除import属性外,其他的页面属性只能出现一次。page指令可以出现在JSP文件的任何地方,通常放在JSP文件的头部。page指令的语法格式
<%@ page attribute = "value" ......%>
其中,attribute 包含 language 、import、session、buffer、autoFlush、isThreadSafe、info、errorPage、contentType、isErrorPage等不同页面指令、具体每个指令的使用格式如下:
<%@ page
[language = "java"]
[import = "{package.class / package.*}, ... "]
[session = "true /false"]
[buffer = "none /8kb/sizekb"]
[autoFlush = "true/false"]
[isThreadSafe = "true/false"]
[info = "text"]
[errorPage = "relativeURL"]
[contentType = "mimeType[;charcterSet]"/"text/html;charset = "ISO-8859-1"]
[isErrorPage = "true/false"]
%>
session属性:该属性默认为ture,表示当前页面支持session。false的目的是节约服务器资源。
buffer属性:设置JSP的out对象的缓冲区大小。默认值由服务器确定。
autoFlush属性:指定缓冲区的工作策略,在缓冲区溢出的情况下,取值为true则正常输出。取值为false则会导致一个溢出错误发生。
isThreadSafe属性:用于指定是否可以处理来自多个用户的请求。
errorPage属性:制定一个异常处理页面。指定的错误页面可以通过预定义的exception变量访问异常
isErrorPage:指定当前页面是否可以真以为其他页面的错误处理页面
contentType属性:用于指定MINE类型
errorPage用来配置本JSP页面的错误处理页面。而web.xml可以指定整个Web应用的错误处理页面。
上面的属性可以单独使用也可以一起使用
<%@ page language="java" import = "java.util.*"
session = "true" buffer = "12kb" autoFlush = "true"
errorPage = "error.jsp"
contentType="text/html; charset=UTF-8"%> <html><head><title>page指令</title></head><body><h2>page指令</h2><center>现在时间是 <%= new java.util.Date()%></center></body>
</html>
<!--
D:\apache-tomcat-8.5.100-windows-x64\apache-tomcat-8.5.100\webapps\ROOT\includeText.jsp -->
10.4.3 taglib属性
jsp页面想要支持JSP标签。就要使用taglib属性。用户可以自定义标签库,为标签编写配置文件,然后就可以在页面中使用已经定义好的标签了。
taglib指令的语法格式如下:
<%@ tagliburi="标签库URI" prefix="自定义标签前缀" %>
10.5 JSP动作元素
与jsp指令元素不同,jsp动作元素在请求处理时起作用。JSP动作元素是用XML语法写成的。利用JSP动作可以动态的插入文件、重用JavaBean组件,把用户重定向到另外的界面,为Java插件生成HTML代码。
JSP引擎在处理JSP文件时,每遇到一个JSP动作元素,就会根据他的标签做相应的处理。常用的JSP动作元素包括:<jsp:forward> <jsp:include> <jsp:plugin> <jsp:setProperty> <jsp:useBean>
等
10.5.1 <jsp:forward>
它将请求转发到另一个JSP、Servlet或者静态资源文件中。
请求转发的资源必须位于与该JSP文件相同的上下文环境中
当遇到这样的标签时,就通知当前网页的操作,转入新的页面操作。
<jsp:forward>
的语法格式如下:
<jsp:forward page="relativeURL" | "<%=expression %>" />
<jsp:forward page="relativeURL" | "<%=expression %>" />
<jsp:param name="pName1" value="pValue1 | <%=expression1 %>" />
<jsp:param name="pName2" value="pValue2 | <%=expression2 %>" />
<jsp:forward>
可以通过<jsp:param>
设置属性,name指定参数名,value指定参数值,参数可以有一个或者多个。并且必须发给一个动态文件。
<jsp:forward>
在Jsp开发中应用最多的是登录功能的实现。当用户登录某系统时,通过用户名和密码认证,使用<jsp:forward>
跳转到主界面。
10.5.2 <jsp:userBean>
<jsp:userBean>
用于在JSP中创建一个Bean实例。指定该实例的作用范围,并且在它的标签指定范围内可用。
```jsp:userBean``的语法格式如下:
<jsp:useBean id="id" class="className" scope = "scope" BeanName = "beanName"/>
id :唯一确定在指定范围内的Bean的变量
class:用于指定Bean的路径名或类名
BeanName:用于通过串行化方法从类中创建一个Bean
type:type可以是类本身、父类或者接口
- scope用来指定Bean变量存在的有效范围。scope的取值可以是page request session
application等,默认值为page <jsp:userBean>``的主体部分可能包括
jsp:userBean 操作。只有在```jsp:userBean``创建实例后才执行主体部分。如果Bean已经存在,则不再执行主体部分。
10.5.3 <jsp:setProperty>
<jsp:setProperty>
实际利用了Bean中的setXXX()方法来设置Bean的属性值
<jsp:setProperty>
的语法如下:
<jsp:setProperty name = "beanName" property = "attributeName" value = "attributeValue"/>
其中,name 指定需要修改属性的 Bean 的名称;property 指定 Bean 的属性,即 Bean 类中的属性;value 是要设定的属性值。
10.5.4 <jsp:getProperty>
<jsp:getProperty>
通常与<jsp:getProperty>
操作噢诶和使用以获得Bean的属性值,并显示在页面中。他访问的属性会自动转换成String类型,然后发送给输出流。
<jsp:getProperty>
的语法如下:
<jsp:getProperty name = "beanName" property = "attributeName">
其中,name 指定需要获取属性的 Bean 的名称;property 指定 Bean 的属性,即 Bean 类中的属性。
10.5.4 <jsp:include>
<jsp:include>
用于在请求过程中在JSP页面里包含静态或动态文本。
jsp:include 的语法如下:
<jsp:include page="relativeURL | <%=expression%>" flush="true" />
page 指定引入页面的路径,flush 表示在引入文件前是否刷新缓冲区,默认为 false。
注意:“jsp”和“:”以及“include”三者之间没有空格。
head.jsp 代码如下:
<p>header内容</p>
index.jsp 代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<body><jsp:include page="head.jsp"></jsp:include><p>编程帮(http://www.biancheng.net)</p>
</body>
</html>
运行结果如下:
10.5.5 <jsp:plugin>
```<jsp:plugin> ```用来产生特别的标识,可以装入Applet或者JavaBean。当JSP文件被编译之后发送给浏览器,浏览器可以根据不同的版本替换这些标识。
<jsp:plugin>
的语法如下:
<jsp:plugin type="bean|applet" code="classFileName" codebase="classFileDirectoryName"
[ name="instanceName" ]
[ archive="URIToArchive, ..." ]
[ align="bottom|top|middle|left|right" ]
[ height="displayPixels" ]
[ width="displayPixels" ]
[ hspace="leftRightPixels" ]
[ vspace="topBottomPixels" ]
[ jreversion="JREVersionNumber | 1.1" ]
[ nspluginurl="URLToPlugin" ]
[ iepluginurl="URLToPlugin" ] >
[ <jsp:params>
[ <jsp:param name="parameterName"
value="{parameterValue | <%= expression %>}" /> ]+
</jsp:params> ]
[ <jsp:fallback> text message for user </jsp:fallback> ]
</jsp:plugin>
示例:
<jsp:plugin type=applet code="Molecule.class" codebase="/html">
<jsp:params>
<jsp:param name="molecule" value="molecules/benzene.mol" />
</jsp:params>
<jsp:fallback>
<p>Unable to load applet</p>
</jsp:fallback>
</jsp:plugin>
10.6 内置对象
为了简化页面的开发过程,JSP 提供了一些内置对象。
JSP 内置对象又称为隐式对象,它们由容器实现和管理。在 JSP 页面中,这些内置对象不需要预先声明,也不需要进行实例化,我们可以直接在脚本和表达式中使用。
JSP内置对象有以下几个:
- out
out对象用来向客户端浏览器输出数据
【实例】
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta charset="ISO-8859-1">
<title>out对象实例</title>
</head><%@ page buffer = "1kb" %> <!-- 设置缓冲区大小 --><body>
<%for(int i = 0;i<100;i++)out.println(i + "{" + out.getRemaining() + "}"); // 输出缓冲区剩余大小%>
<br>缓冲区大小:<%= out.getBufferSize() %><br>
剩余缓冲区大小:<%=out.getRemaining() %><br>
自动刷新:<%=out.isAutoFlush() %><br></body></html>
- request
request对象又被称为请求对象,可以获得客户端提交的数据和客户端的相关信息,即客户端的请求信息被封装到request对象中,服务器通过request对象才能得知客户端的请求,然后做出相应的处理
【实例】
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ page import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta charset="ISO-8859-1">
<title>request对象实例</title>
</head><body>
<form action="" method = "post">
用户名:<input type="text" name="username"> <br/>
密码:<input type="password" name="userpass" > <br/>
<input type="submit" value="进入">
</form><%
String str = "";
if(request.getParameter("username")!=null && request.getParameter("userpass")!=null){//获取request参数Enumeration enumt = request.getParameterNames(); //获得参数的名称while(enumt.hasMoreElements()){ //变量参数名称str = enumt.nextElement().toString();//参数名称转换为字符串out.println(str+":"+request.getParameter(str)+"<br>");//输出参数名称}
}
%>请求方式:<%=request.getMethod() %><br>请求的资源:<%=request.getRequestURI() %><br>请求用的协议:<%=request.getProtocol() %><br>请求的文件名:<%=request.getServletPath() %><br>请求的服务器IP:<%=request.getServerName() %><br>请求服务器的端口:<%=request.getServerPort() %><br>客户端IP地址:<%=request.getRemoteAddr() %><br>客户端主机名:<%=request.getRemoteHost() %><br></body></html>
- response
response对象时用来做出相应的。当客户端向服务器端提交请求时,就会产生request对象,该对象会对客户端的请求做出反应,并向客户端输出相关的信息
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ page import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta charset="ISO-8859-1">
<title>response.sendRedirecttitle</title>
</head><body>
<%String address = request.getParameter("web");if(address!=null){if(address.equals("baidu"))response.sendRedirect("https://www.baidu.com/");else if(address.equals("bing"))response.sendRedirect("https://cn.bing.com/?mkt=zh-CN");else if(address.equals("weibo"))response.sendRedirect("https://weibo.com/"); //respnse的重定向方法 }
%>
<b>选择跳转</b>
<form action = "response.jsp" method = "GET">
<select name = "web"><option value = "baidu" selected>https://www.baidu.com<option value = "bing">https://cn.bing.com<option value = "weibo">https://weibo.com
</select><input type = "submit" value = "提交"></form>
</body>
</html>
4. session
session(会话)对象,是用来保存每个用户的信息,达到对每个用户的状态进行跟踪的目的。
从用户打开浏览器与服务器建立连接,到关闭浏览器断开与服务器的连接,称为一次会话。
用户第一次访问JSP页面时,JSP引擎会自动产生一个session对象,并分配一个String类型的ID,同时将ID发送到客户端,存放在Cookie中。
当客户端再次访问这个网页时,就不会再分配新的session对象,直到关闭浏览器。
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%> <!-- 支持库 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta charset="ISO-8859-1">
<title>session对象实例 </title>
</head><body>
session.getCreateionTime():<%=session.getCreationTime() %><br>session.getId()<%=session.getId() %><br>session.getLastAccessedTime()<%=session.getLastAccessedTime() %><br>new java.sql.Time(session.getLastAccessedTime())<%= new java.sql.Time(session.getLastAccessedTime()) %><br>session.getMaxInactiveInterval()<%=session.getMaxInactiveInterval() %><br>
session.isNew()?<%=session.isNew()?"是":"否" %><br>
<%session.putValue("name", "小明");session.putValue("password", "123456");session.putValue("age", "25");%>
<%for(int i =0;i<session.getValueNames().length;i++){ //遍历session的属性,并输出属性和属性值out.println(session.getValueNames()[i]+"="+session.getValue(session.getValueNames()[i])+"<br>");}
%></body></html>
5. application
application对象用来保存全局的数据信息,对于同一个JSP引擎来说,所有的用户都共享application对象,该对象在服务器启动时创建,一直保持到服务器关闭
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ page import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta charset="ISO-8859-1">
<title>application对象演示</title>
</head>
<body><br>
Tomcat引擎以及版本号<%=application.getServerInfo() %>
返回application.jsp虚拟路径的真实路径<%=application.getRealPath("/application.jsp") %><br><br>
服务器支持的Servlet API的大版本号<%=application.getMajorVersion() %><br><br>
服务器支持的Servlet API的小版本号<%=application.getMinorVersion() %><br><br>指定资源(文件及目录)的URL路径:<%=application.getResource("/application.jsp") %><br><br>
<%
application.setAttribute("name", "Java从入门到放弃"); //设置application对象的属性值
out.println(application.getAttribute("name")); //输出application对象的属性
application.removeAttribute("name"); //删除application对象的属性和值
out.println(application.getAttribute("name")); //输出application对象的属性
%><%if(application.getAttribute("count")==null)application.setAttribute("count","1");elseapplication.setAttribute("count",Integer.toString(Integer.valueOf(application.getAttribute("count").toString()).intValue()+1));%>
是第<%=application.getAttribute("count") %>位访问者</body>
</html>
6. pageContext
PageContext对象可以完成对JSP页面内可见的,特殊的预定义对象的范文,因此可以访问到该JSP页面所有的session对象,也可以取得application对象的属性值
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>编程帮(www.biancheng.net)</title>
</head>
<body><%request.setAttribute("info", "request范围的值");session.setAttribute("info", "session范围的值");application.setAttribute("info", "application范围的值");%>利用 pageContext 取出以下范围内各值(方法一):<br> request 设定的值:<%=pageContext.getRequest().getAttribute("info")%><br> session 设定的值:<%=pageContext.getSession().getAttribute("info")%><br> application 设的值:<%=pageContext.getServletContext().getAttribute("info")%><hr>利用pageContext取出以下范围内各值(方法二):<br> 范围1(page)内的值:<%=pageContext.getAttribute("info", 1)%><br> 范围2(request)内的值:<%=pageContext.getAttribute("info", 2)%><br> 范围3(session)内的值:<%=pageContext.getAttribute("info", 3)%><br> 范围4(application)内的值:<%=pageContext.getAttribute("info", 4)%><hr>利用 pageContext 修改或删除某个范围内的值:<%pageContext.setAttribute("info", "修改request范围的值", 2);%><br> 修改 request 设定的值:<br><%=pageContext.getRequest().getAttribute("info")%><br><%pageContext.removeAttribute("info");%>删除 session 设定的值:<%=session.getAttribute("info")%>
</body>
</html>
7.exception对象
如果在Jsp页面中出现没有捕获的异常,就会生成exception对象,并把它传送到在page指令中设定的错误页面中,然后在错误处理页面中处理相应的exception对象。exception对象只有在错误处理页面(在页面指令里isErrorPage=true)才可以使用。
8.config对象
config对象保存了Servlet的配置信息,当JSP引擎启动时,自动将JSP引擎的配置信息保存于config对象里。
10.8.1 静态include指令和动态include指令的比较
- 静态include主要是对静态页面引入,不会检查所包含文件的变化<%@file = “include.html”%>。
动态include主要是对动态页面的引入,它总会检查所引入的页面的变化,如果包含的资源在请求间变化,则在下一次请求包含jsp:include动作的JSP时,将包含资源的新内容。 - 在转换时,如果所包含资源发生变化,则使用include指令的JSP将不能反映出新的内容,除非重新编译这个JSP
jsp:include动作包含的属性有两个
- page:指定所包含资源的相对URL路径,该资源必须是同一Web应用程序的组成部分
- flush:指定在执行include动作后是否应刷新缓冲区。
10.8.2 指令和动作的区别
1.include指令
include指令可以在JSP页面转换成Servlet之前将JSP代码插入其中。但难以维护,只要被包含的页面发生改变,就要更改主页面,因为主页面不会自动查看被包含的页面是否发生更改。
语法格式:
<%@ include file = "sample.jsp" %>
2.include动作
-
jsp:include 动作是在主页面被请求时,将次级页面的输出包含进来。服务器按照正常的方式对指想被包含资源的URL进行解释。因而这个URL可以是Servlet或JSP页面。
-
在被包含的页面发生更改时,无需对主页面做出修改。
-
缺点是所包含的是次级页面的输出,而非次级页面的实际代码,所以在被包含的页面中不能使用任何有可能在整体上影响主页面的JSP构造。
语法格式:
<jsp:include page="{relativeURL|<%=expression%>>}" flush="true"><jsp:param name="parametername" value="parametervalue"/>
</jsp:include>
参考资料
JSP out对象