您的位置:首页 > Web前端 > JavaScript

JSP 脚本调用 Java 代码

2014-04-01 17:25 239 查看
转自:http://blog.sina.com.cn/s/blog_5ec67df20100hso1.html

点击这里,了解:安装
JDK、Tomcat、中文编码问题(这里涉及的所有源文件及 Tomcat 均采用 utf-8 编码)
点击这里,了解:简单配置
Tomcat、servlet 模版、如何运行 servlet
点击这里,了解:用于各例程的
servlet 工具类 ServletUtil.java


一、JSP 脚本元素

使用 JSP 脚本元素可以将 Java 代码插入到与 JSP 页面相对应的 servlet 中。脚本元素有3种形式:

形如
<%= Java expression_r %> 的表达式,它们在求值后插入到 servlet 的输出之中。
形如
<% Java Code %> 的 scriptlet,它们将插入到 servlet 的 _jspService 方法(由 service 方法调用)中。
形如
<%! Field / Method Declaration %> 的声明,它们将插入到 servlet 类的定义中, 不属于任何已有的方法。

大多数情况下,JSP文档的大部分由静态文本(一般是HTML))构成,称之为模板文本(template text)。几乎从任何方面看,这种 HTML 都类似于普通的 HTML,它们遵循所有相同的语法规则,为处理该页面而创建的 servlet 只是将它们原封不动地传递给客户程序。这些 HTML 不仅看起来很普通,还可以使用任何已有的用于构建网页的工具(例如,Dreamweaver 或 Frontpage)创建它们。

如果输出中含有 <% 或 %>,需要在模板文本中使用 <\% 或 %\>。如果希望添加一段注释,使之出现在 JSP 页面中但不出现在结果文档中,需要使用

<%!-- JSP Comment --%>

下面这种形式的 HTML 注释按照常规的方式传递给客户程序:

<!-- HTML Comment -->


二、JSP 中调用动态代码的策略

在 JSP 中可以使用许多不同的方式生成动态内容。这些方式中的每一种都有其合理的应用范围。在决定哪种方式更为恰当时,项目的大小和复杂度是需要考虑的最重要的因素。人们更容易犯将太多代码直接放在页面中的错误,这种情况发生的机率要比其对立面大得多。尽管对于简单的应用,将少量的 Java 代码直接放到 JSP 页面中也工作得很好,但如果在 JSP 页面中使用大量复杂的 Java 代码块,造成的后果是难以维护,难以调试,难以重用,并且很难在开发团队的不同成员间划分工作。

下面列出的在 JSP 中调用动态代码的策略是按照从“简单应用或小型开发团队” → “复杂应用或大型开发团队”而从上至下排列的:

直接调用 Java 代码。将所有的 Java 代码都放在 JSP 页面中。只适用于极少量的代码。
间接调用 Java 代码。开发单独的实用工具类。只在 JSP 页面中插入调用实用工具类所需的 Java 代码。
使用 bean。开发单独的实用工具类,按照 bean 的要求进行构造。使用 jsp:useBean、jsp:getProperty 和 jsp:setProperty 调用该代码。
使用 MVC 构架。由一个servlet 负责处理最初的请求,查找数据,并将结果存储在 bean 中,然后将请求转发到 JSP 页面来提交最后的结果。JSP 页面使用 bean。
使用 JSP 表达式语言。使用简写语法访问并输出对象的属性。一般与 bean 和 MVC 组合使用。
使用定制标签。开发标签处理类。用类 XML 的定制标签调用标签处理器。

无论是25行代码,还是1000行代码,最好都放在 Java 类中,然后使用一或两行基于 JSP 的 Java 代码调用它。理由如下:

开发

我们一般在面向 Java 的开发环境中(IDE,如 JBuider 或 Eclipse;或者代码 编辑器,如 UltraEdit 或 emacs)编写常规的类。一般在面向 HTML 的环境中,如 Dreamweaver 编写 JSP。面向 Java 的开发环境一般在平衡圆括号、提供工具提示、检查语法、代码着色等方面做得更好。
编译

如果要编译常规的 Java 类,只需在 IDE 中单击 Build 或调用 javac;要编译 JSP 页面,则必须将它放到正确的目录中,启动服务器,打开浏览器并输入相应的 URL。
调试

在编写 Java 类或 JSP 页面时,语法上的错误在所难免。如果在常规的类定义中含有语法错误,编译器会马上告诉我们,还会给出代码中错误所在的行。如果在 JSP 页面中存在语法错误,服务器一般提示错误出现在 servlet(即由 JSP 转换成的 servlet)中哪一行。如果要在运行期间输出跟踪信息,对于常规的类,如果所使用的 IDE 没有提供更好的方法,也可以使用简单的 System.out.println 语句。在 JSP 中,虽然有些情况下可以使用打印语句,但这些打印语句显示在什么地方则因服务器而异。
工作划分

许多大型的开发团队由精通 Java 语言的人员和精通 HTML,但对 Java 知之甚少,甚至一无所知的人员组成。直接出现在页面中的 Java 代码越多,Web 开发人员就越难以操作它。
测试

假定希望制作一个 JSP 页面,输出指定区间的某个随机整数。如果直接在 JSP 页面中执行这些运算,那么,在测试时,必须一次一次地调用该页面,检查是否得到指定区间内的所有数字,且区间之外的数字没有出现。将 Reload 按钮点击了数十次之后,就会对测试感到厌烦。但是,如果在常规 Java 类的静态方法中完成这项任务,则可以编写测试例程,由它在循环中调用该方法,这样就可以成百上千次地运行测试用例,没有任何问题。对十更复杂的方法,可以保存输出,只要对方法做出修改,就用新的输出与之前保存的结果进行比较。
重用

将一些代码放到 JSP 页面中,后来,发现需要在不同的 JSP 页面中完成相同的事情。应该怎么办呢?剪切、粘贴?以这种方式重复代码是万恶之源,因为如果要对代码做出更改,那么必须更改很多不同地方的代码。解决代码重用的问题是面向对象编程的全部内容。不要仅仅因为使用 JSP 来简化 HTML 的生成,就忘记所有那些好的 OOP 基木准则。

对于常规 servlet,由于可以使用分离的 Web 应用来避免与其他项目中的 servlet 发生名称冲突,因此有时使用默认的包也是合理的。然而,对于 JSP 所调用的代码,则一定要使用包。同时,由于在编写供 servlet 使用的实用工具类时,并不知道后来是否同样会在 JSP 中使用它,因而,所应采取的策略是:所有的类,不管是供 servlet 还是 JSP 页面使用,都应该使用包。


三、使用预定义变量

可用的变量是 request、response、out、session、application、config、pageContext 和 page。还有一个附加变量 exception,但仅仅在错误页面中才可用。

Request

这个变量是与请求相关联的 HttpServletRequest,可以通过它访问请求的参数、 请求的类型(如 GET 或 POST)和输入的 HTTP 报头(例如 cookie)。
Response

这个变量是与发往客户的响应相关联的 HttpServletResponse。由于输出流一般都会缓冲,在 JSP 页面的主体内设置 HTTP 状态代码和响应报头一般是合法的,尽管在已经有输出送往客户的情况下,servlet 中不允许设置报头和状态代码。但是,如果将缓冲关闭,必须在提供任何输出之前设置状态代码和报头。
Out

这个变量是用来将输出发送到客户程序的 Writer。但是,为了在 JSP 页面中的各个地方都可以设置响应报头,此处使用的 out 不是标准的 PrintWriter,它对输出的内容进行缓冲(JspWriter 类型)。可以使用 page 指令的 buffer 属性调整缓冲区的大小。由于 JSP 表达式会被自动放入到输出流中,从而很少需要直接引用 out,故而 out 变量几乎仅仅用在 scriptlet 中。
Session

这个变量是与请求相关联的 HttpSession 对象。JSP 中会话是自动创建的,因此即使不存在对输入会话的引用,也存在这个变量。例外的情况是,如果使用 page 指令的 session 属性禁用自动会话跟踪,则不存在这个变量。并且,这种情况下对 session 变量的引用在 JSP 页面转换成 servlet 时会引起错误。
Application

这个变量和 getServletContext 返回的类型相同,都为 ServletContext。servlet 和 JSP 页面可以在 ServletContext 对象中(而非实例变量中)存储持续性数据。ServletContext 拥有 setAttribute 和 getAttribute 方法,使用它们可以存储与指定键关联的任意数据。将数据存储在实例变量中或是存储在 ServletContext 中,二者之间的差异是:ServletContext 由 Web 应用中所有的 servlet 和 JSP
页面共享,而实例变量只能由存储数据的同一个 servlet 使用。
Config

这个变量是该页的 ServletConfig 对象。原则上可以使用它来读取初始化参数,但在实践中,初始化参数在 jspInit 中读取,而非 _jspService。
PageContext

JSP 引入一个名为 PageContext 的类,通过它可以访问页面的许多属性。PageContext 类拥有 getRequest、getResponse、getOut、getSession 等方法。pageContext 变量存储与当前页面相关联的 PageContext 对象的值。如果方法或构造函数需要访问多个与页面相关的对象,传递 pageContext 要比传递多个 request、response、out 等的独立引用更容易。
Page

这个变量不过是 this 的同义词,没有什么太大的用处。创建它是为了在脚本语言还不是 Java 的时代用作占位符。


四、JSP 调用 Java 代码实例

下面是一个 JSP 调用动态代码的实例 JspTest.jsp,包括了脚本元素调用 Java 代码的所有3种形式。将此文件放在 Tomcat 的安装目录 $Tomcat/webapps/ROOT 下,启动 Tomcat,然后就可以通过 http://localhost:8080/JspTest.jsp 调用它。其中用到了工具类 ServletUtil,可以通过此页面顶部的链接查看之。

<?xml version="1.0" encoding="UTF-8" ?>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>随机数列表</title>

<%!private int randomNum = cn.foololdfat.ServletUtil.randomInt(100);%>

</head>

<body>

<h1>随机数列表</h1>

<p><b>保存在实例变量中的随机数,只在对象构建时初始化:</b></p>

<ul>

<li><%=this.randomNum%></li>

</ul>

<p><b>保存在临时变量中的随机数,随机数的个数也是随机的:</b></p>

<ul>

<%

int numEntries = cn.foololdfat.ServletUtil.randomInt(10);

for (int i = 0; i < numEntries; i++)

out.println("<li>" + cn.foololdfat.ServletUtil.randomInt(100) + "</li>");

%>

</ul>

<p><b>其他一些 JSP 的例子:</b></p>

<ul>

<li><b>当前时间:</b><%=new java.util.Date()%></li>

<li><b>服务器类型:</b><%=application.getServerInfo()%></li>

<li><b>Session ID:</b><%=session.getId()%></li>

</ul>

</body>

</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: