UML软件工程组织

使用J2EE的XSL文件自动生成JavaBeans
作者:Klaus P. Berg著; 陈姣姣 翻译
概要

编写生成动态内容的Java 2平台企业版应用程序的一个方法是使用servlets、 JavaBeans、XML、 HTML、和 XSLT (可扩展样单语言转换)。在本技巧中,作者Klaus Berg着眼于HTML格式参数如何自动转换为 JavaBeans。格式参数是嵌入到XSL文件中的HTML的一部分。产生的Bean可作为J2EE程序中的中间存储器使用,并可容纳以HTML格式输入的由用户输入的代码。一般的,Bean转换为XML树。XML树提供输入给XSL转换,XSL转换最终产生HTML输出给用户。

在Java 2平台企业版的世界里,servlet组件在服务器端编写applet,并完善Java定义在客户端/服务器层和在多捆绑应用程序中的地位。如今,J2EE 在Java 的接受方面,在许多完善Java的现有技术如XML、XSLT(可扩展样单语言转换)以及Java 对象对XML 的转换中的地位突出。许多地方可帮助你学习servlets、 XML/XSLT、和 HTML (见 Resources),因此我在这里不必费口舌讨论这些技术,而是集中解决在使用这种技术的Web 服务开发者的日常生活中扮演重要角色的问题:编写Java 语句来摘录HTML格式要素传递的参数值并产生相应的作为中间存储器使用的JavaBeans。这种beans可管理应用程序客户端(浏览器)和运行在J2EE服务器上的组件之间的数据流动,也可以管理服务器组件和数据库之间的数据流动。他们要么保存用户以HTML格式输入的数据,或者,更多的是保存在URL上传递的或者在POST中传递的属性。例如:用于逻辑页的 bean具有两种属性:逻辑和密码。在处理请求的过程中,这种bean可转换为XML树。

图1展示了一个基于Sun 微系统的J2EE推荐模式和设计图(见Resources)的J2EE应用程序的总体结构。StrutsCX, 用于建立企业版应用程序的开放式源框架,也使用类似的结构。



Figure 1. J2EE application architecture using Java, XML, HTML, and XSLT. Click on thumbnail to view full-size image.


第一步,用户通常需要填写输入格式并使用HTTP GET或者POST请求发送该数据给服务器。前控制器servlet (前控制器也是Sun J2EE 模式)检测请求并给出一个或多个帮助类。帮助类的重要任务包括:阅读用户发送的请求参数,必要时测试他们的合法性,以及将他们储存在JavaBean内。所以,提交给用户的每一个页面都对应一个 JavaBean。 JavaBean在大家熟知的模型视图控制器(MVC)中用作HTML视图的模型。

当bean填满用户表格数据后,可以转换为XML(如使用 Castor,一种转换Java对象为XML的开放式源项目)。这种XML信息流就是产生HTML输出的XSL转换的输入。XSLT是万维网联盟(W3C)的官方标准,它灵活而且强大,适用于XML数据结构到文本、PDF、 HTML/XHTML (可扩展HTML)、无线标记语言(WML)、 VoiceXML、或者任何其它XML 格式的转换。XSLT处理器如Xalan 或者Saxon实际上使用XSL样单实现转换,XSL样单本身也是一种XML文档(见图2)。你可以为XSL样单内部的XML数据的转换定义规则。XSLT处理器在转换过程中使用这些规则。注:本文提到的转换指的是从XML到HTML的转换。



Figure 2. Principle of XSLT


探讨HTML表格

我们使用servlets、XML、和 XSL来创建动态HTML输出页。现在让我们进一步探讨传递用户输入数据的HTML表格要素。如上文所述,这些HTML语句是嵌入到XSL文件之内的。因此,我们得先研究XSL文件,才知道servlet的帮助者类检测用户请求时必须阅读哪种HTML输入参数。如果用户在表格中填写了数据或者在选择框内或者在单选框内做出选择的话,每个HTML表格元素都会有一个名字和一个传递的值。相关的表格标记有:

<input type="text" name="text_parameter_name"...
<input type="checkbox" name="checkbox_parameter_name"...
<input  type="radio name="radio_button_name"...
and sometimes we need hidden parameters too, e.g.,
<input type="hidden" name="ReportName" value="First_Report"/>


如果需要检测用户使用Java语言填写的这些表格标记的数据的话,我们可以使用servlet的请求对象。对应的语句如下:

String inputText1 = request.getParameter("text_parameter_name");
// Then check for null value
更好的方法是使用O'Reilly ParameterParser: 
import com.oreilly.servlet.ParameterParser;
ParameterParser parser = new ParameterParser(request);
String inputText1= parser.getStringParameter("text_parameter_name", "");
// Provides a default value ("") too
This parser is especially useful when dealing with checkboxes:
boolean someBooleanValue = parser.getBooleanParameter("checkbox_parameter_name", false);


在Java语句中作为字符串使用的HTML表格参数名字的正确与否很关键。你应该从XSL文件中拷贝和粘贴到Java源代码中或者读取XSL文件中的参数名然后键入到Java源代码内。除此之外没有其他方法了。虽然很麻烦但很少出错。而且每个HTML表格参数值都在Java变量内,我们需要将这些值储存在相应的、作为HTML页的中间模型使用的JavaBean中,直到数据保存到数据库或者企业信息系统内为止。这就是说,我们得先手工编写JavaBean的代码或者也可以从IDE处获得少许支持,然后调用每一个 bean设置器方法储存这些值。 这里就到本文中的Java技巧了。

两个发生器

我开发了两个发生器,在处理Java和XSL时它们可以减轻J2EE开发者的负担。第一个发生器为JavaBean 发生器,第二个发生器为参数解析器和bean "过滤器"发生器(它可以生成用于第一个代码发生器产生的JavaBean 的设置方法调用)。这些发生器都是基于正规的表达语句。我使用Jakarta正规表达式,所以可以不限于Java 2 平台标准版 (J2SE) 1.4。两个发生器都使用参数解析器,它允许你指定命令行中的某些参数(如产生的 JavaBean 可用于特定的Java软件包并可实现接口或者扩展超类)。源代码中最让人感兴趣的地方就是正规的表达式定义块:

// The RE Patterns
    private static final RE titlePattern = new RE("<title.+(/>|</title>)",
RE.MATCH_CASEINDEPENDENT);
    private static final RE inputLinePattern = new RE("(<!--.*)|((<input.+(/>|</input>))|
(<select[^>]+>)|(<textarea[^>]+>l))", RE.MATCH_CASEINDEPENDENT);
    private static final RE hiddenPattern = new RE("type\\s*=\\s*\"hidden\"",
RE.MATCH_CASEINDEPENDENT);
    private static final RE textPattern = new RE("type\\s*=\\s*\"text\"",
RE.MATCH_CASEINDEPENDENT);
    private static final RE cbPattern = new RE("type\\s*=\\s*\"checkbox\"",
RE.MATCH_CASEINDEPENDENT);
    private static final RE radioPattern = new RE("type\\s*=\\s*\"radio\"",
RE.MATCH_CASEINDEPENDENT);
    private static final RE namePattern = new RE("name\\s*=\\s*\"[^\"]+\"",
RE.MATCH_CASEINDEPENDENT);


如你所见,所有相关的HTML表格标记都是这些模式的一部分。XslBeanGenerator (见 Resources)浏览用于这些标记的XSL文件并且产生相应的 JavaBeans。在这些JavaBeans中,参数名可以转换为bean 的成员变量。XslParameterParser 的职责有二:他首先产生代码阅读servlet请求对象之外的HTML表格标记参数值,然后产生代码使用JavaBean的设置器方法将这些值储存在相应的JavaBean内。产生的代码如下:

import com.oreilly.servlet.ParameterParser;
// Generated statement: use O'Reilly ParameterParser
ParameterParser parser = new ParameterParser(request);
// Generated statement
String username = parser.getStringParameter("username", "");
// Generated statement: read the HTML input text value
UserDataModel model = new UserDataModel();
// This statement or similar must be inserted by the user

// It instantiates the generated JavaBean
model.setUsername(username);
// Generated statement: calling bean setter method


要得到XSL文件的完整实例以及两个解析器的源代码,你可从Resources处下载。

继续解析

该技巧介绍了两个XSL文件解析器,当与基于Java、XML、XSL、和XSLT 的J2EE应用程序一起运行时会生成有用的Java代码。两个发生器,XslBeanGenerator 和XslParameterParser, 填补了XSL文件和依赖于主要由这些XSL文件的HTML提供的信息的Java代码之间的空隙。一个发生器产生了储存使用XSL/HTML 描述的用户数据的JavaBean 。另一个发生器生成了阅读HTML请求参数值和储存这些值到相应的bean 的Java代码语句。

关于作者

Klaus Berg 毕业于德国的卡尔斯鲁厄大学的电气工程和信息学专业。他在西门子公司从事项目的设计和实现,主要是使用Swing 和 Java Web Start从事 Java 绘图用户界面的开发。他现在的工作是使用服务器端的Java 开发内联网应用程序。

本文译自:http://www.javaworld.com/javatips/jw-javatip141.html?

版权所有:UML软件工程组织