《Java Web程序设计任务教程》简要复盘:第六章 JSP技术

it2024-01-05  85

《Java Web程序设计任务教程》简要复盘:第六章 JSP技术

第六章 JSP技术什么是JSPJSP的运行原理JSP的基本语法JSP指令page指令include指令 JSP隐式对象九个隐式对象out 对象pageContext 对象exception 对象 JSP动作元素include 动作元素forward 动作元素其他的动作元素 作者:氯磷Rolin

目录:

第一章:网页开发基础(无)第二章:Java Web概述第三章:Servlet基础第四章:请求与响应第五章:会话及其会话技术第六章:JSP技术第七章:EL表达式和JSTL第八章:Servlet的高级特性第九章:JDBC第十章:数据库连接池与DBUtils工具第十一章:JSP开发模型第十二章:文件的上传和下载

第六章 JSP技术

在动态网页的开发中,经常需要动态生成HTML内容,如果使用Servlet来实现HTML页面的更新,需要调用大量的输出语句,使静态和动态内容混合在一起,导致程序非常臃肿。 为了克服这些缺点,Oracle(SUN)公司推出了JSP技术。

什么是JSP

JSP全名Java Server Pages,它用于简捷而快速的生成Web界面因为Servlet展示信息不方便,所以引入了JSP技术JSP本质上是一个Servlet!!JSP就是在HTML页面的基础上嵌入了Java代码JSP也拥有java的众多特征,例如:跨平台性,业务代码相分离,组件重用,预编译等

JSP的运行原理

原理图 JSP的具体运行过程 客户端发出请求给JSP容器(Tomcat),请求访问JSP文件JSP容器将JSP文件转换成一个Java Servlet源文件,如果出错则会输出错误信息JSP容器再将Java Servlet源文件编译成相应的*.class字节码文件由Tomcat加载*.class文件,创建一个Servlet实例,并且调用jspInit()方法进行初始化执行jspService()方法处理客户端的请求。和Servlet一样,多个客户端同时请求该JSP文件则JSP容器也会创建多个线程来处理它们。如果JSP文件被修改了,则根据设置服务器将决定是否对该文件进行重新编译。由于第一次调用时需要转换和编译,往往会产生一些延迟或卡顿当请求处理完成后,响应对象由JSP容器接收,并将HTML格式的响应信息发送回客户端由于系统资源不足或其他原因,JSP容器可能会以某种不确定的方式将编译好的Servlet移出内存,此时Servlet会先调用jspDestroy()方法,然后该实例会被加入垃圾回收系统处理

虽然JSP类不实现Servlet接口,但是继承自HttpJspBase类 由于HttpJspBase类是HttpServlet的一个子类,由此JSP编译生成的java类实质上就是一个Servlet

JSP的基本语法

JSP文件中可以嵌套很多内容,例如JSP的脚本元素和注释等,这些内容的编写需要遵循一定的语法规范

JSP脚本元素

JSP脚本元素是指嵌套在<%和%>之间的Java程序代码。通过JSP脚本元素可以将Java代码嵌入到HTML页面中,所有可执行的Java代码都可以通过JSP脚本来执行

JSP脚本元素主要包括如下三种类型: JSP ScriptletsJSP 声明语句JSP 表达式 JSP脚本元素语法: 标签语法用途程序代码标签(JSP Scriptlets)<% 此处输入Java程序代码 %>编写Java程序代码,但不可以定义代码,此时在编译后这段代码是放在jspService()里的JSP声明语句<%! 变量或方法的声明 %>声明JSP内所使用的成员方法、成员变量、静态方法、静态变量、静态代码块等 在其声明的方法在整个JSP页面都有效,此时在编译后这段代码是放在jspService()外的JSP表达式<%=变量%>用于将程序数据输出到客户端,即将java中的变量或者表达式的值输出到页面上JSP注释<%-- 注释信息 --%>Tomcat在编译JSP页面时会自动忽略JSP注释内容,不会将注释信息发送到客户端。而在JSP页面编写的HTML注释会被发送到客户端

JSP指令

JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言。

为了设置JSP页面的一些信息,Sun公司提供了JSP指令。JSP2.0中定义了page、include等指令,每种指令都定义了各自的属性。

page指令

page指令称为页面指令,用来定义JSP页面的全局属性,该配置会作用域整个页面。 page指令的属性可以定义MIME类型、定义需要导入的包、错误页的指定等。

page指令的语法格式如下: <%@page 属性1=“属性值1” 属性2=“属性值2”%>page指令的常用属性: 属性名称取值范围描述languagejava指明解释该JSP文件时采用的语言,默认为Javaimport任何包名和类名指明在JSP页面翻译成Servlet时导入的包或类。是唯一一个可以多次引用的指令属性sessiontrue\false指明该JSP内是否内置Session对象,默认为trueisErrorPagetrue\false指定该页面是否为错误处理页面,如果为true,则说明内置Exception对象的exception,可以直接使用errorPage某个JSP页面的相对路径指定一个错误页面,如果该JSP抛出一个未被捕捉的异常,则转到该属性指定的页面contentType有效的文档类型客户端浏览器根据该属性判断文档类型pageEnCoding当前页面指定页面编码格式 page指令的其他属性: 属性名称描述extends指定JSP页面产生的Servlet继承的父类buffer指定缓冲区的大小,默认是8KB。如果为none,则表示不设置缓冲区。(此属性要和autoFlush一起使用)autoFlush指定输出缓冲区即将溢出时,是否强制输出缓冲区的内容。可以设置为true或false(默认为true)isThreadSafe指定JSP是否支持多线程。可以设置为true或false,若为true,则表示该页面可以处理多个用户的请求;如果为false,则此JSP一次只能处理一个页面的用户请求。info设置JSP页面的相关信息。可以使用servlet.getServletInfo()方法获取到JSP页面中的文本信息isELIgnored指定JSP文件是否支持EL表达式

除了import属性外,其他的属性都只能出现一次,否则会编译失败。 page指令的属性名称都是区分大小写的

include指令

include指令是文件加载指令,用于在JSP中插入一个包含文件或代码的文件,这个包含的过程是静态包含。

它把文件插入后与原来的JSP文件合并成一个新的JSP页面(注意:如果被插入的内容发送改变,则包含这个页面的JSP文件就需要重新编译)。

具体语法: <%@ include file="head.html"%> 属性 include指令只有一个file属性,该属性用来指定插入到JSP页面目标位置的文件资源。 插入文件的路径一般不以/开头,而是使用相对路径示例:在一个网站所有链接都插入同一个导航栏

在一个空白的HTML页面中直接使用include指令

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>测试页面</title> <link href="${pageContext.request.contextPath}/css/usercenter.css" type="text/css" rel="stylesheet"/> <link rel="icon" type="image/ico" sizes="128x128" href="img/n9.ico"/> </head> <body> <%@include file="/part/top.jsp"%> </body> </html>

其中top是顶部栏,具体代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <link href="../css/top.css" rel="stylesheet" type="text/css"/> <script src="${pageContext.request.contextPath}/js/top.js" type="text/javascript"></script> </head> <body vlink="gray" onload="updatepage('<%=username%>','<%=id%>')"> <div class="top" > <ul class="toplist"> <li><a href="/index.jsp"><p class="text">主页</p></a></li> <li><a href="javascript:alert('收藏夹还未开放');"><p class="text">收藏</p></a></li> <li><a href="javascript:alert('资源站还未开放');" ><p class="text">资源站</p></a></li> <li><a href="/login.jsp" id="logina"><p class="text" id="login">登录</p></a></li> <li><a href="/reg/reg.jsp" id="rega"><p class="text" id="reg">注册</p></a></li> <li><a href="#"><p class="text">更多</p></a></li> </ul> </div> </body> </html>

打开浏览器运行工程,从浏览器可知网页的源代码如下:

<html> <head> <title>测试页面</title> <link href="/css/usercenter.css" type="text/css" rel="stylesheet"/> <link rel="icon" type="image/ico" sizes="128x128" href="img/n9.ico"/> </head> <body> <html> <head> <title>Title</title> <link href="../css/top.css" rel="stylesheet" type="text/css"/> <script src="/js/top.js" type="text/javascript"></script> </head> <body vlink="gray" onload="updatepage('Rolin','4')"> <div class="top" > <ul class="toplist"> <li><a href="/index.jsp"><p class="text">主页</p></a></li> <li><a href="javascript:alert('收藏夹还未开放');"><p class="text">收藏</p></a></li> <li><a href="javascript:alert('资源站还未开放');" ><p class="text">资源站</p></a></li> <li><a href="/login.jsp" id="logina"><p class="text" id="login">登录</p></a></li> <li><a href="/reg/reg.jsp" id="rega"><p class="text" id="reg">注册</p></a></li> <li><a href="#"><p class="text">更多</p></a></li> </ul> </div> </body> </html> </body> </html>

在以上的静态包含中,实际上是先将所包含的文件的内容导入到包含页中,然后在一起进行编译,最后再将以份整齐的内容展现给用户,即:先包含,再集中进行编译处理。

include指令将top.jsp页面的<head>也一起导入到了页面中

JSP隐式对象

我们可以在_jspService方法中找到对应的局部变量,这些变量我们称之为隐式对象(又叫内置对象)。提供内部隐式对象的目的是为了简化JSP开发JSP 隐式对象是 Web 容器加载的一组类不需要由JSP的编写者实例化,它们由JSP容器实现和管理。在所有JSP页面中都能使用内部对象。内部对象只对表达式和Scriptlet(Java代码)有用,在声明中不能使用。隐式对象的名称是 JSP 的保留字

隐式对象说白了就是我们不需要声明的对象,可以直接拿来使用

九个隐式对象

JSP2.0规范提供了9个隐式对象,它们是JSP默认创建的,可以在JSP中直接使用 名称类型描述outjavax.servlet.jsp.JspWriter输出对象,用于页面输出requestjavax.servlet.http/HttpServletRequest获取客户端请求信息,主要用于接受http协议传送到服务器的数据responsejavax.servlet.http/HttpServletResponse代表客户端的响应,主要用于将jsp容器处理过的对象传送到客户端configjavax.servlet.ServletConfig服务器配置对象,可以获得初始化配置数据sessionjavax.http.HttpSession代表浏览器的一次回话,用来保存用户信息applicationjavax.servlet.ServletContext代表当前的web应用类似于一个全局变量,所有用户的共享信息pagejava.lang.Object当前页面转化后的Servlet类实例pageContextjavax.servlet.jsp.PageContext页面的上下文对象,可以从中获取到当前页面的其他信息,可以从中获取到其他8个隐含对象exceptionjava.lang.Throwable用来处理jsp文件在执行时所产生的错误和异常,在错误页中才起作用

out 对象

在JSP页面中,经常需要向客户端发送文本内容,这时可以使用out对象来实现,他的作用与ServletResponse.getWriter()方法非常类似,都是用来向客户端发送文本形式的实体内容

out对象的类型为JspWriter,相当于一种带缓存功能的PrintWriter。下面将通过一张图来描述out和Servlet引擎之间的工作关系: out隐式对象写入的数据相当于将数据插入到JspWriter对象的缓冲区,只有调用了ServletResponse.getWriter()方法,缓冲区的数据才能真正写入到Servlet引擎所提供的缓冲区中。

如果在JSP页面中,如果调用如下代码: <% out.println("First message <br />"); response.getWriter().println("Second message <br />"); %>

运行代码后你会发现他所输出的是: Second message First message 即使out.println()语句在response.getWriter().println()之前

由此可以说明,out对象通过print语句写入数据后,直到整个JSP页面结束,out对象中输入缓存区的数据“First message”才会真正写入到Servlet的缓冲区中,而response.getWriter().println()语句则是之间写入到Servlet的缓冲区中,Servlet引擎会按照写入缓冲区中数据的存放的顺序输出内容

使用page指令可以设置out对象的缓冲区大小 将page指令修改为如下: <%@ page language="java" contentType="text/html; charset=UTF-8" buffer="0kb" %>

这样out.println()输出的数据就能够直接写入到Servlet引擎所提供的缓冲区了

pageContext 对象

在JSP页面中,使用pageContext对象可以获取JSP的其他八个隐式对象。获取隐式对象的方法如下表 方法名描述JspWriter getOut()用于获取out隐式对象Object getPage()用于获取page隐式对象ServletRequest getRequest()用于获取request隐式对象ServletResponse getResponse()用于获取response隐式对象HttpSession getSession()用于获取session隐式对象Exception getException()用于获取exception隐式对象ServletConfig getServletConfig()用于获取config隐式对象ServletContext getServletContext()用于获取application隐式对象 在JSP页面中,pageContext 还提供了存储数据的功能,其存储数据是通过操作属性实现的: 方法名称功能描述void setAttribute(String name , Object value , int scope)设置pageContext对象的属性Object getAttribute(String name, int scope)获取pageContext对象的属性void removeAttribute(String name , int scope)删除指定范围内名称为name的属性void removeAttribute(String name)删除所有范围内名称为name的属性Object findAttribute(String name)从4个域中查找名称为name的属性 其中参数 scope 指定的是属性的作用范围。其有四个值: pageContext.PAGE_SCOPE : 表示页面范围pageContext.REQUEST_SCOPE : 表示请求范围pageContext.SESSION_SCOPE : 表示会话范围pageContext.APPLICATION_SCOPE : 表示Web应用程序范围 当使用 findAttribute() 方法查找属性时,会从page -> request -> session -> application的顺序依次查找,如果找到,则返回属性的名称,如果找不到,则返回null。

exception 对象

在JSP页面中,经常需要处理一些异常信息,这时可以通过exception对象来实现。

exception对象只有在错误页中才可以使用,要确保isErrorPage = "true"

最常用的一个方法是 显示之前页面的错误信息: <%=exception.getMessage() %>

JSP动作元素

JSP动作元素常用来控制JSP的行为,执行一些常用的JSP页面动作。通过动作元素可以实现多行Java代码能够实现的效果:包含动态页面,实现请求转发等

include 动作元素

在JSP页面中,为了把其他资源的输出内容插入到当前的JSP页面的输出内容中,JSP技术提供了<jsp:include>动作元素

具体的语法格式如下 <jsp:include page="relativeURL" flush="true" />

在上述语法格式中,page属性用于指定被引入资源的相对路径;flush属性用于指定是否将当前页面的输出内容刷新到客户端,默认flush的值为false

工作原理 将被包含的页面编译处理后将结果包含在页面中。 当浏览器第一次请求一个使用<jsp:include>包含其他页面的页面时,Web容器首先会编译被包含的页面,然后将编译处理后的返回结果包含在页面中,之后编译包含页面,最后,将两个页面组合到一起返回给浏览器

与include指令的区别

<jsp:include>标签中要引入的资源和当前JSP页面是两个彼此独立的执行实体,即被动态引入的资源必须能够被Web容器独立执行。而include指令只能引入遵循JSP(HTIML)格式的文件,被引入的文件与当前JSP文件需要共同合并才能翻译成一个Servlet源文件。<jsp:include>标签中引入的资源是运行时才包含的,而include指令引入的资源是在编译之前包含的,包含的是源代码。<jsp:include>标签运行原理与RequestDispatcher.include()类似,即被包含的页面不能改变响应状态码或者设置响应头。而include指令没有这方面的限制。include动作则在Servlet中使用include方法来引入被导入页面的内容。因此include指令执行时不需编译,速度快;include动作需要加载执行,速度慢;include指令执行时将被导入页面的jsp代码完全融入,两个页面融合成一个Servlet;

forward 动作元素

<jsp:forward>动作元素是将当前请求转发到其他Web资源(HTML页面、JSP页面或Servlet等),在执行请求转发之后当前页面将不再执行,而是执行该元素指定的目标页面

请求转发执行时URL地址栏不会发生变化语法格式 <jsp:forward page="welcome.jsp">

page属性用于指定请求转发到的资源的相对路径,该路径是相对于当前JSP页面的URL

其他的动作元素



最新回复(0)