JSP 应用开发教学难点要点剖析
- 首页 >> Web摘要:针对page 指令中有关页面编码的contentType属性与pageEncoding属性,声明的变量定义与Scriptlet中变量的定义,include指令与include 动作,forward 动作转向response 内置对象sendRedirect 方法转向,request 内置对象的getParameter 方法与getAttribute 方等难点和要点进行深入剖析,阐述如何更好地提高课堂教学质量。
0 引言
JSP (Java Server Page) 是基于Java 语言的一种Web 应用程序开发技术,利用这一技术可以
建立安全、跨平台的先进动态网站。利用JSP 技术创建的Web 应用程序,可以实现动态页面与静态页面的分离[1]。与其它Web 技术相比,JSP具有跨平台、编译后运行等特点。JSP 应用开发已经成为高校计算机专业重要的专业课程。在JSP 基本语法中有些概念容易混淆且较难理解,大部分教材对此没有作深入的介绍,在JSP应用开发课程教学中将这些基本概念讲清楚、讲透彻是提高课堂教学质量的关键。通过多年教学实践,笔者对这些难点要点进行了研究探讨。1 p a g e 指令的c o n t e n t T y p e 属性与pageEncoding属性pageEncoding 属性指定的编码是JSP 文件本身的编码,contentType属性指定的编码是服务器发送给客户端时的网页内容编码,是Servlet 类输出网页时使用的编码。Web 服务器在处理JSP 网页时,要经过3 个阶段的转化:①将JSP 文件翻译成Servlet 源文件(一种Java 类)。在这个阶段的转化过程中,根据pageEncoding 设定的编码读取JSP 文件,形成统一的UTF—8 编码的 Servlet 源文件。不论JSP 页面编写时用的是什么编码方案,经过这个阶段的结果全部是UTF—8 编码的java 源文件;
②将Servlet 源文件编译成字节码的class 文件,编译器按UTF—8 编码读取java 源文件,编译成UTF—8 编码的字节码;③服务器载入和执行Servlet 字节码类文件,将输出结果发送到客户端的浏览器显示。这个阶段使用contentType 属性指定的编码来输出HTML 形式的结果。pageEncoding和contentType 的默认设置都是 ISO—8859—1。通常只要设定其中一个,另一个也随之相同,当然二者的设置完全可以不同,但pageEncoding 属性指定的编码必须与JSP源文件保存的编码一致,而contnetType属性设置的编码应与浏览器显示时选择的编码一致。下面的网页在Windows 中文版记事本中用默认编码(ANSI)保存后,发布至Tomcat6.0 服务器,从浏览器中可正常显示。
< % @ p a g e i m p o r t = " j a va . u t i l . D a t e "
pageEncoding="gb2312"contentType="text/html;
charset=utf—8" %>
<%-- 使用Page 指令,引入Date 类、设置
JSP 源文件的编码为gb2312、输出到客户端编码
为utf—8 --%>
<html>
<head><title>JSP 基本语法</title></head>
<body>
<h1> page 指令示例页面</h1>
<%
Date current=new Date();
/* 获取当前的日期和时间 */
out.print(“当前时间是:”+
current);/* 在页面中输出当前的日期和时间*/
%>
</body>
</html>
如果将page 指令改为<%@ page import="java.util.Date"pageEncoding="utf—8" contentType="text/html; charset=gb2312" %>,则只有用UTF—8 编码保存网页,才能在浏览器中正常显示,否则会出现乱码。当然浏览器的编码设置为自动选择,前一个页面显示时浏览器选择的编码为UTF—8,而后一个页面显示时浏览器选择的编码为GB2312。
2 声明中的变量定义与Scriptlet中变量的定义JSP 编译为Servlet 类时,Scriptlet 被包含在Servlet 的Service 方法中。多个Scriptlet 可以按照在JSP 中出现的顺序合并成一个。在一段Scrptlet 中定义的变量和创建的对象,可以在另一个Scriptlet 中使用[2]。 JSP 编译为Servlet 时,声明中的变量和方法作为Servlet 类的字段和方法。声明中定义的变量属类变量,是全局性的,而Scriptlet中定义的变量属于Service方法,是局部变量。
<%@ page contentTy p e = " t e x t/ h t m l ;
charset=gb2312" %>
<html>
<head>
<title>JSP 基本语法</title>
</head>
<body>
<h1>Scriptlet 变量与Declaration 变量比
较页面</h1>
<%!
int varClass=1;
%>
<%
int varMethod=1;
%>
Declaration 中的变量为:<%= varClass++
%> <br>
Scriptlet 中的变量为:<%= varMethod++
%>
</body>
</html>
刷新该页面,或者用新的窗口再次打开该页面,声明中的变量值在增加,而Scriptlet 中变量值不变。
3 include指令与include动作include 指令用于在当前JSP 页面中指令所在位置将指令指定的资源内容包含进来,被包含的资源可以是JSP 文件、HTML 文件、本文件、inc 文件等,这些文件中都可以包含JSP 代码,实际上不管被包含文件的扩展名是什么类型,JSP 解析器一律将其作为JSP 文件对待,转化为Servlet 时进行语法检查。include 指令包含是静态的,即包含过程发生在编译时;被包含的内容将会被插入到Servlet源文件中去。JSP 文件
编译后,被静态包含的内容就不可改变,如果改变了被包含文件的内容而要使改变在包含文件中生效,必须重新编译JSP 文件,但静态包含的执行效率高。
<jsp:include> 动作中被包含的资源与include指令一样,可以是JSP 文件、HTML 文件、文
本文件、inc 文件等,但对JSP 文件要单独进行编译,而对其他类型的文件只作为静态的文本插入到输出的网页中,所以除JSP 文件外,其他被包含的文件中不能有JSP 代码[3-5]。被包含的JSP 文件只有对JspWriter 对象的访问权,并且不能设置头或者Cookie。如果页面输出是缓存的,那么缓存区的刷新要优先于包含的刷新。<jsp:include>动作包含是动态的,即在请求运行时包含,它不把被包含的内容插入到编译的JSP 文件中,而是采用请求时调用的方式。资源的路径和名称不需要在编译前确定,可以动态的生成,详见表1。<jsp:include>动作在执行效率上比include指令要低。<jsp:include>动作在转化成的Servlet类中翻译的语句为:org.apache.jasper.runtime.JspRuntimeLibrary.include(request,response,strPath , out, false);。方法转向地址可以是任何URL;<jsp:forward>动作转向是在服务器端进行的,利用服务器的输出缓冲机制实现,如果在 <jsp:forward> 之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,那么<jsp:forward> 将不起作用。response 对象的sendRedirect 方法是通过修改HTTP 协议的HEADER 部分,对浏览器下达重定向指令。它将转向后的地址发送到客户端,由浏览器重新进行一次请求;<jsp:forward> 动作转向后浏览器地址栏中的URL 没有变化,response
对象sendRedirect方法转向后浏览器地址栏中显示新的URL,forward 动作与sendRedirect 方法比较,详见表2。表 2 forward 动作与sendRedirect 方法比较语法转向前后的作用域实现机制转向范围<jsp:forward page=“anUrl”> 同一请求作用域中request在服务器端实现,浏览器地址栏中的URL没有变化同一应用程序上下文response.sendRedirect (“anUrl”) 同一会话作用域中session转向地址要发送到客户端,由浏览器重新进行请求可转向任意URL
表 1 两种include 包含的比较语法状态资源类型描述
<%@ include file =“” %>编译时包含,被包含的内容插入到Servlet 类中。.txt .inc .html(.htm) .jsp,所有类型的资源都作同样的包含处理,静态。JSP 引擎将对所包含的文件进行语法分析,对各种类型的被包含文件都作为JSP 文件对待。
<jsp:include page =“” />
运行时包含,被包含的内容插入到输出的网页中。.txt .inc .html(.htm) .jsp,JSP 文件作为动
态包含,其他类型的文件静态输出。JSP 引擎不对所包含的文件进行语法分析,对被包含的JSP 文件单独编译,采用请求时调用的方式,而对其他类型的被包含文件只作为静态文本插入到输出的网页中。
4 f o r w a r d 动作与r e s p o n s e 内置对象sendRedirect方法response 对象的sendRedirect 方法与<jsp:forward> 动作的作用都是页面转向,但二者有着显著的区别。<jsp:forward>动作转向前后的网页在同一个请求(request)作用域,转向后的网页还可以获取客户端提交的数据。response 对象sendRedirect 方法转向前后的网页不在同一个请求上下文数据,只能在同一个会话(session)对上下文进行数据捕捉,不可能再获取request 上下文中的数据;<jsp:forward> 动作只能在同一个应用程序间重定向。response 对象sendRedirect
5 request内置对象的getParameter方法与getAttribute方法通过getParameter 方法获取客户端提交的参数,一般是客户端提交的表单数据或URL 中带的查询参数,这个数据只能是字符串类型;getAttribute 方法获取服务器端设置的属性,这个数据必须预先由setAttribute 方法设置,不经过网络传输,可以是任何Java 数据类型,getAttribute方法获取数据后全部作为Object 类型,需强制转化为原来的类型进行处理。request 对象没有也不需要setParameter 方法[5]。
6 结语
JSP 技术中还有一些重要且容易混淆的基本概念,如Session 与Cookie,但这些概念的辨析
可在很多教材和文献中见到,而对上述概念许多文章的解释都很模糊,对其辨析很少有资料涉及且知识点零散。今后的工作我们将更深入地研究JSP 应用开发课程的学习和讲授方法。