Topic: <下一代WEB开发模型> |
Print this page |
1.<下一代WEB开发模型> | Copy to clipboard |
Posted by: nothing Posted on: 2003-05-26 00:22 下一代WEB开发模型 发布日期:2003-3-30 发 布 者:51jsp.net 自从Web诞生之日起,Web开发者都试图为如何更好、更快、更加方便的开发出动态Web页面而绞尽了脑汁。从最开始的CGI开始,然后是各种嵌入式脚本语言(PHP、ASP、JSP),接着又在各种脚本语言的基础上发展各种应用框架或是模板语言。 但是如上这些林林总总的解决方案却仍然面临这样一个尴尬的问题,那就是:和传统发展了十几年的桌面IDE集成开发环境相比,这些开发方式仍然显得是那么的原始。WEB开发者不得不面对嵌入式脚本语言、HTML、JavaScript以及SESSION数据库连接等等各式各样混杂在一起的复杂问题,开发者需要学习和使用这些所有的东西。没有什么东西可以帮助开发者有效而又一致的管理它们。光从开发者使用的工具就知道了:看看有多少人还在使用UltraEdit和vi,其它的工具能够带来多大的帮助?更多的时候是在增加麻烦而已。 现在事情似乎有了一丝转机。微软随着ASP.NET推出的一个全新开发模式:基于事件驱动的WebForm。完全类似传统GUI程序的开发方式,通过在功能强大的Visual Studio.NET集成环境的拖放、事件编程,就可以完成大部分WEB开发工作。然后系统自动将其转换到传统WEB运行模式。开发效率得以大大提升。与此同时,在Java的WEB解决方案中也诞生了一项类似的技术――ECHO。同样也是基于事件驱动的开发方式。虽然到目前为止还为没有如Visual Studio.NET一般完善的IDE集成环境。但是在诸如Eclipse中实现它也并非难事。 作为一项全新开发技术,WebForm和ECHO究竟能为Web开发领域带来多大影响现在还很难说。毕竟WEB和传统的GUI开发有着巨大差异。WEB有着无比丰富的页面表现形式,绝非那千篇一律的Windows窗口可以比,开发者在开发不得不考虑到这一点,如何和页面美工配合作出功能完善而又漂亮的页面,绝非易事。还有一个重要的问题那就是WEB的执行效率。显然,复杂的驱动模型带来的是更低的效率。如何平衡好这之间的关系,仍然需要仔细考虑。 在这个专题里,我们列出ASP.Net和JSP中相关的一些技术背景,但是更多是我们希望你能加入到这项新技术的话题讨论中。 Web开发框架中的架构模式比较(一) 发布日期:2003-3-30 发 布 者:51jsp.net 转 自:http://www.csdn.net Web开发框架中的架构模式比较 (Wang Hailong) 目录 Web开发框架中的架构模式比较... 1 目录... 1 序... 1 架构模式Architectural Pattern的基本概念... 2 Server Page (页面内容和逻辑)... 2 ASP.Net的例子... 3 JSP的例子... 5 XSP的例子... 7 页面控件重用... 8 页面内容和表现风格的分离,(XSLT)... 9 页面输入验证 Validation. 12 ASP.Net的例子... 12 Apache Struts的例子... 13 Apache Cocoon的例子... 14 Database driven page. 15 多语言支持... 16 用户身份确认Authentication 和授权Authorization. 17 ASP.Net的服务器端配置文件web.config例子。(节录)... 17 Java web 框架的服务器端配置文件web.xml例子。... 18 SOAP Web Service. 19 序 本文讨论两大类web开发框架——java web框架和微软的.Net框架之间的架构模式的比较。 涉及到的Java web 框架包括:Cocoon,Struts,Axis,Xalan等Apache开源项目,SourceForge.net的开源项目Echo。 涉及到的架构模式Architectural Pattern包括: Server Page, (页面内容和逻辑) 页面控件重用,(TagLib) 页面内容和表现风格的分离,(XSLT) 页面输入验证 Validation, Database driven page, 多语言支持, 用户身份确认Authentication 和授权Authorization, SOAP Web Service。 架构模式Architectural Pattern的基本概念 软件开发中的模式,根据处理问题的粒度不同,从高到低,分为3个层次: 架构模式 Architectural Pattern 设计模式 Design Pattern 实现模式 Implementation Pattern 架构模式 Architectural Pattern 是模式中的最高层次,表示最基本的系统组成,通常提供一组预定义的子系统。比如,用户和文件系统安全策略模型,N-tier结构,组件对象服务,名字服务(Naming Service),服务端Session Keeping and Tracing;再比如,Container模式——在J2EE技术中,web server是servlet和jsp的container,Application Server是EJB的Container;还有,我们熟知的MVC结构也属于架构模式的层次。 设计模式 Design Pattern是模式中的第二层次,用来处理程序设计中反复出现的问题。 例如,[Gang of Four]总结的23个基本设计模式 —— Factory Pattern, Observer Pattern等等。 实现模式 Implementation Pattern 是最低也是最具体的层次,处理具体到编程语言的问题。比如,类名,变量名,函数名的命名规则;异常处理的规则,等等。 本文通过举例(java和.Net)说明web开发框架中的一些架构模式。 Server Page, (页面内容和逻辑) 页面控件重用,(TagLib) 页面内容和表现风格的分离,(XSLT) 页面输入验证 Validation, Database driven page, 多语言支持, 用户身份确认Authentication 和授权Authorization, SOAP Web Service。 Web开发框架中的架构模式比较(二) 发布日期:2003-3-30 发 布 者:51jsp.net Server Page (页面内容和逻辑) Server Page技术也可以称为服务端脚本技术。 ASP.Net的服务端脚本语言包括VB.Net,C#.Net,J#.Net,JScript.Net。微软的IIS Web Server支持多种服务端脚本语言,是微软的战略决策之一。当然,既然这些Web服务程序的脚本只能运行在IIS Web Server中,那么也就只能运行在Windows平台上。这里有一点很值得注意,ASP.Net的服务端脚本的用法和JSP(还有后面提到的XSP)大不一样。ASP.Net的服务端脚本和页面元素之间的交互,如同客户端JavaScript一般。难怪,JScript.Net也被包括到服务端脚本之列。这种方式的优越性显而易见,ASP.Net程序员在处理一般的Web界面交互事件时,不用考虑很多HTTP Request – Response Cycle,而JSP(或XSP)程序员必须时时刻刻把这一点记在脑子里。JSP(或XSP)一般只用来动态生成网页,不进行事件处理。Java Web框架通常采取MVC (Model – View - Control)结构,页面交互转换的事件机制在Control部分实现。稍后会举例说明。 JSP的服务端脚本语言包括Java。根据最新推出的JSP2.0规范(可从java.sun.com站点下载),可以看出,JSP力图向XML规范靠拢,并引入Expression Language和大量的TagLib,试图尽量把Java语言代码从JSP页面中清除出去,以解决JSP页面固有的Java Code Pollution问题。JSP页面现在确实好看了许多,更加结构化,更加清晰。但在我看来,不过是拿另一种脚本语言(TagLib和Expression Language)来取代Java Code中的一部分功能罢了,副作用就是要求页面设计或编程人员多掌握一门语言。而且,在实际应用的要求中,要想使这门新语言达到java语言的灵活和强大,不是一件容易的事情,而且可能会令TagLib和Expression Language越来越庞大复杂,难以掌握。稍后会举例说明。 基于java的另一种Server Page技术是Apache Cocoon项目中的XSP技术。(如果需要进一步了解Apache Cocoon和XSP,请访问xml.apache.org站点)。Apache Cocoon项目大量使用SAX/XSLT技术。XSP用来为后续的转换处理管道Pipeline提供XML内容,而且XSP页面本身的生成,也要经过不少XSLT转换。XSP技术中也包括TagLib的概念,称为LogicSheet,表现形式也和JSP中相似,但实现原理完全不同。JSP的TagLib通过Java Tag Extension Class实现,XSP的TagLib(LogicSheet)通过XSLT转换实现。XSP技术的LogicSheet机制能够把页面的内容和逻辑从物理上分离开,分成几个不同的文件。稍后会举例说明。 ASP.Net的例子 例子1。说明服务端脚本调用Page_Load()函数(ASP.Net的内嵌初始化函数)生成页面元素的例子,从.Net框架文档中摘出。 <%@ Page Language="C#" %> <%@ Import Namespace="System.Data" %> <HTML> <script runat="server"> void Page_Load(Object sender, EventArgs e) { DataTable dt = new DataTable(); DataRow dr; dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32))); dt.Columns.Add(new DataColumn("StringValue", typeof(string))); dt.Columns.Add(new DataColumn("DateTimeValue", typeof(DateTime))); dt.Columns.Add(new DataColumn("BoolValue", typeof(bool))); dt.Columns.Add(new DataColumn("CurrencyValue", typeof(double))); for (int i = 0; i < 9; i++) { dr = dt.NewRow(); dr[0] = i; dr[1] = "Item " + i.ToString(); dr[2] = DateTime.Now; dr[3] = (i % 2 != 0) ? true : false; dr[4] = 1.23 * (i+1); dt.Rows.Add(dr); } MyRepeater.DataSource=new DataView(dt); MyRepeater.DataBind(); } </script> <body> <h3>Data Binding with the HtmlAnchor</h3> <p> <form runat=server> <asp:Repeater id="MyRepeater" runat="server"> <ItemTemplate> Link for <a href=''<%# DataBinder.Eval(Container, "DataItem.StringValue", "detailspage.aspx?id={0}") %>'' runat="server"> <%# DataBinder.Eval(Container, "DataItem.StringValue") %> </a> <p> </ItemTemplate> </asp:Repeater> </form> </body> </HTML> 例子2。说明web界面中的事件响应机制。并说明了如何在Web 窗体页中注册和声明自定义服务器控件。该控件的标记前缀是 Custom,它创建的类出现在 CustomWebFormsControls 命名空间中。它是使用 Custom:MyButton 标记在页的正文中声明的。我们可以看到TagLib的影子。 <%@ Register TagPrefix="Custom" Namespace="CustomWebFormsControls" Assembly="CustomControls" %> <HTML> <script language="C#" runat=server> private void Button_Click(Object sender, EventArgs e) { TextBox.BackColor = System.Drawing.Color.Green; TextBox.Text = "You clicked the button"; } </script> <body> <form method="POST" action="MyButton.aspx" runat=server> Here is our custom button.<br> <Custom:MyButton id="Button" OnClick="Button_Click" runat=server/> <br> <br> <asp:TextBox id = "TextBox" Text = "Click the button" Width = "200" BackColor "Cyan" runat=server/> <br> </form> </body> </HTML> JSP的例子 例子1。 下面的文件是Apache Struts项目的struts-config.xml配置文件例子,从struts用户文档中摘录。Apache Struts采用MVC (Model – View - Control)结构。struts-config.xml是重要的Control部分的配置文件,定义页面之间的交互,相当于用户界面的事件机制。 <struts-config> <form-beans> <form-bean name="logonForm" type="org.apache.struts.webapp.example.LogonForm" /> </form-beans> <global-forwards type="org.apache.struts.action.ActionForward" /> <forward name="logon" path="/logon.jsp" redirect="false" /> </global-forwards> <action-mappings> <action path="/logon" type="org.apache.struts.webapp.example.LogonAction" name="logonForm" scope="request" input="/logon.jsp" unknown="false" validate="true" /> </action-mappings> </struts-config> 例子2。下面的JSP例子从JSP2.0规范中摘录,说明TagLib和Expression Language在JSP中看起来是什么样子。注意,<%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core” %>,其中,JSTL表示JSP Standard Tag Library。${x}和${result}是Expression Language的用法。 <%-- page.jsp --%> <%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core” %> <%@ taglib prefix=”my” tagdir=”/WEB-INF/tags” %> <c:set var=”x” value=”1”/> ${x} <%-- (x == 1) --%> <my:example var=”x”> ${x} <%-- (x == 2) --%> ${result} <%-- (result == null) --%> <c:set var=”x” value=”3”/> <c:set var=”result” value=”invisible”/> </my:example> ${x} <%-- (x == 4) --%> ${result} <%-- (result == ‘invisible’) --%> <%-- /WEB-INF/tags/example.tag --%> <%@ attribute name=”var” required=”true” %> <%@ variable alias=”result” name-from-attribute=”var” scope=”AT_BEGIN” %> <%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core” %> ${x} <%-- (x == null) --%> ${result} <%-- (result == 1) --%> <c:set var=”x” value=”ignored”/> <c:set var=”result” value=”2”/> <jsp:doBody/> ${x} <%-- (x == ‘ignored’) --%> ${result} <%-- (result == 3) --%> <c:set var=”x” value=”still_ignored”/> <c:set var=”result” value=”4”/> XSP的例子 下面的例子从Apache Cocoon项目的用户文档中摘录。说明LogicSheet在XSP中的使用。LogicSheet在XSP的作用,相当于TagLib在JSP中的作用。JSP的TagLib通过Java Tag Extension Class实现,XSP的TagLib(LogicSheet)通过XSLT转换实现。 文件1是XSP文件,greeting3.xml;文件2是LogicSheet文件,logicsheet.greeting.xsl;生成的结果是文件3,greeting.xml。 文件1 —— greeting3.xml <?xml version="1.0"?> <xsp:page xmlns:xsp="http://apache.org/xsp" xmlns:greeting="http://duke.edu/tutorial/greeting"> <greeting> <greeting:hello-world/> </greeting> </xsp:page> 文件2 —— logicsheet.greeting.xsl <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsp="http://apache.org/xsp" xmlns:greeting="http://duke.edu/tutorial/greeting" version="1.0"> <xsl:template match="xsp:page"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="greeting:hello-world"> <!-- more complex XSLT is possible here as well --> <xsp:logic> // this could be arbitrarily complex Java code, JDBC queries, etc. String msg = "Hello, world!"; </xsp:logic> <xsp:expr>msg</xsp:expr> </xsl:template> <!-- This template simply copies stuff that doesn''t match other --> <!-- templates and applies templates to any children. --> <xsl:template match="@*|node()" priority="-1"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> 文件3 —— 结果 greeting.xml <?xml version="1.0"?> <greeting>Hello, world!</greeting> 注意,logicsheet.greeting.xsl文件,java代码嵌在<xsp:logic>和</xsp:logic>中间。XSP或者LogicSheet文件中的java代码中能够很自然地嵌入xml元素。而在JSP页面中,java代码和HTML元素交织在一起。 页面控件重用 正如前面所述,JSP和XSP中的页面控件重用,主要通过TagLib机制对html元素进行封装,实现页面控件的重用。。比如,Struts重定义了几乎所有html元素标签;Sun公司提出了SP Standard Tag Lib标准;Apache Jakarta Taglibs项目提供了括JSTL在内的多类TagLib的实现。Apache Cocoon项目提供了一些内嵌的LogicSheet —— Request, Form等。用户自定义控件,需要继承实现Java Tag Extension Class ——javax.servlet.jsp.tagext.TagSupport 。 有些java web框架走向另一个方向。SourceForge.net的java开源项目Echo是一个典型的例子。Echo不使用JSP,甚至不使用html,只使用Servlet。Echo提供了一组类似于Swing的接口,程序员可以象开发Applet程序一样写Web程序。Echo框架是事件驱动的框架。程序员书写的类Swing控件,会被Echo框架翻译成对应的html元素。用户自定义控件,只需要按照类Swing接口,生成自定义的控件类即可。 ASP.Net的页面控件重用方式和TagLib机制类似。同时,ASP.Net又是事件驱动的框架,这一点和Echo框架类似。ASP.Net似乎找到了一个比较好的平衡点。ASP.Net定义了两组服务器控件 —— HTML服务器控件,和Web服务器控件。HTML服务器控件封装了简单的html页面元素,比如,form,button,input等;Web服务器控件封装了更为复杂多样的页面控件,比如,asp:Calendar,asp:CheckBoxList等。HTML服务器控件在页面中的书写方法不带前缀,几乎和普通html页面元素一样,只是扩展了一些属性。Web服务器控件带有asp前缀。可以把HTML服务器控件类比为基本的TagLib,可以把Web服务器控件类比为扩展的TagLib。用户自定义控件需要继承System.Web.UI.WebControls.WebControl或者System.Web.UI. Control。并按照类似于TagLib声明的格式,写在页面文件中:<%@ Register TagPrefix= "myNameSpace" TagName="myUserControl" Src="userControl1.ascx" %> Web开发框架中的架构模式比较(三) 发布日期:2003-3-30 发 布 者:51jsp.net 页面内容和表现风格的分离,(XSLT) 页面内容和表现风格分离的第一步,是CSS风格文件和HTML页面的分离,但是,HTML的页面内容和显示元素还是紧紧捆绑在一起。XML推广之后,XSLT也大行其道,大量地应用在web发布系统中。ASP.Net和java web框架都在朝这个方向走,只是java web框架走得更快,更远。下面进行说明。 在处理XSLT时,SAX接口要比DOM接口快得多,而且几乎不占据内存空间。令人不安的是,.Net框架到现在还没有提供SAX接口。微软提供了一套MSXML SDK,其中包含了基于COM组件的SAX实现,并提供了在VB和VC中应用的实例。MSXML SAX的VC用例中,需要包含头文件msxml2.h。这就是说,.Net框架无法以一种自然的方式调用MSXML SAX。还有,.Net框架的XSLT是如何实现的,即,System.Xml.Xsl.XslTransform是用什么方式实现的,是调用SAX接口,还是DOM接口。如何使用.Net框架组成一条XSLT的处理管道?我也找不到方法。也没有发现这方面的例子。 Apache Xerce项目支持XML处理,提供Java和C++版本,并提供了调用MSXML的封装;Apache Xalan项目支持XSLT处理;Apache Cocoon2.0,使用SAX接口,组成XSLT的处理管道。 Apache Xalan项目的一个例子文件UseXMLFilters.java UseXMLFilters.java。(节录,文件头部分省略) public class UseXMLFilters { public static void main(String[] args) throws TransformerException, TransformerConfigurationException, SAXException, IOException { // Instantiate a TransformerFactory. TransformerFactory tFactory = TransformerFactory.newInstance(); // Determine whether the TransformerFactory supports The use uf SAXSource // and SAXResult if (tFactory.getFeature(SAXSource.FEATURE) && tFactory.getFeature(SAXResult.FEATURE)) { // Cast the TransformerFactory to SAXTransformerFactory. SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory); // Create an XMLFilter for each stylesheet. XMLFilter xmlFilter1 = saxTFactory.newXMLFilter(new StreamSource("foo1.xsl")); XMLFilter xmlFilter2 = saxTFactory.newXMLFilter(new StreamSource("foo2.xsl")); XMLFilter xmlFilter3 = saxTFactory.newXMLFilter(new StreamSource("foo3.xsl")); // Create an XMLReader. XMLReader reader = XMLReaderFactory.createXMLReader(); // xmlFilter1 uses the XMLReader as its reader. xmlFilter1.setParent(reader); // xmlFilter2 uses xmlFilter1 as its reader. xmlFilter2.setParent(xmlFilter1); // xmlFilter3 uses xmlFilter2 as its reader. xmlFilter3.setParent(xmlFilter2); // xmlFilter3 outputs SAX events to the serializer. Serializer serializer = SerializerFactory.getSerializer (OutputProperties.getDefaultMethodProperties("xml")); serializer.setOutputStream(System.out); xmlFilter3.setContentHandler(serializer.asContentHandler()); // Perform the series of transformations as follows: // - transformer3 gets its parent (transformer2) as the XMLReader/XMLFilter // and calls transformer2.parse(new InputSource("foo.xml")). // - transformer2 gets its parent (transformer1) as the XMLReader/XMLFilter // and calls transformer1.parse(new InputSource("foo.xml")). // - transformer1 gets its parent (reader, a SAXParser) as the XMLReader // and calls reader.parse(new InputSource("foo.xml")). // - reader parses the XML document and sends the SAX parse events to transformer1, // which performs transformation 1 and sends the output to transformer2. // - transformer2 parses the transformation 1 output, performs transformation 2, and // sends the output to transformer3. // - transformer3 parses the transformation 2 output, performs transformation 3, // and sends the output to the serializer. xmlFilter3.parse(new InputSource("foo.xml")); } } } Apache Cocoon项目的一个配置文件例子sitemap.xmap Apache Cocoon项目的sitemap.xmap定义了XSLT处理管道。见下例中的<map:handle-errors>部分,错误信息经过两次XSLT处理," error2document.xsl" 和"apache.xsl"。 /sample/tutorial/sitemap.xmap (节录,无关部分省略) … <map:pipelines> <map:pipeline> <map:match pattern="*-dept.xml"> <map:act set="process"> <map:parameter name="descriptor" value="context://tutorial/docs/department-form.xml"/> <map:generate type="serverpages" src="docs/confirm-dept.xsp"/> <map:serialize type="xml"/> </map:act> <map:generate type="serverpages" src="docs/{1}-dept.xsp"/> <map:serialize type="xml"/> </map:match> ... <map:handle-errors> <map:transform src="stylesheets/system/error2document.xsl"/> <map:transform src="stylesheets/apache.xsl"/> <map:serialize status-code="500"/> </map:handle-errors> </map:pipeline> ... </map:pipelines> ASP.Net的Xml Web控件例子 下面的示例从.Net框架文当中摘录,说明如何使用 Xml 控件通过示例 XSL 转换文件来显示示例 XML 文件。示例 XML 文件名为 People.xml,示例 XSL 转换文件名为 Peopletable. xsl。可以看到,asp:Xml控间只能进行一步XSLT转换。 <html> <body> <h3>Xml Example</h3> <form runat="server"> <asp:Xml id="xml1" DocumentSource="people.xml" TransformSource="peopletable.xsl" runat="server" /> </form> </body> </html> Web开发框架中的架构模式比较(四) 发布日期:2003-3-30 发 布 者:51jsp.net 页面输入验证 Validation ASP.Net提供验证功能的服务器控件: CompareValidator验证两个控件输入之间的比较,RangeValidator检查用户的输入是否在指定的上限和下限之间;RegularExpressionValidator 控件检查输入是否与某个正则表达式所定义的模式相匹配(社会保障号、电子邮件地址、电话号码、邮政编码等);RequiredFieldValidator 控件确保用户不会略过某个输入;CustomValidator 控件创建自定义服务器和客户端验证代码。稍后会举例说明。 Java web框架通常会把验证规则提出来,放在一个验证规则文件里。Apache Struts提供验证两种方式。一种是重载org.apache.struts.action.ActionForm类的validate方法,一种是定义Validator Plug-In文件,validator-rules.xml。Apache Cocoon也提供了类似的验证规则文件。稍后举例说明。 ASP.Net的例子 摘自.Net框架文档,其余部分省略,只保留了关于RegularExpressionValidator的部分。本例中,id为RegularExpressionValidator1的控件的ControlToValidate属性为TextBox1,所以,RegularExpressionValidator1负责验证TextBox1是否符合正则表达式"\d{5}"——5个数字。 <td> <asp:TextBox id="TextBox1" runat="server"/> </td> <td> <asp:RegularExpressionValidator id="RegularExpressionValidator1" ControlToValidate="TextBox1" ValidationExpression="\d{5}" Display="Static" EnableClientScript="false" ErrorMessage="Zip code must be 5 numeric digits" runat="server"/> </td> Apache Struts的例子 下面的例子从Apache Struts的用户文档中摘录出来。Apache Struts提供的Validation机制非常强大,能够实现基于其它输入域的条件验证,即,如果另外一个或几个输入域都符合相应的情况,那么,验证当前域是否符合某种条件。 <form name="dependentlistForm"> <field property="firstName" indexedListProperty="dependents" depends="requiredif"> <arg0 key="dependentlistForm.firstName.label"/> <var> <var-name>field[0]</var-name> <var-value>lastName</var-value> </var> <var> <var-name>field-indexed[0]</var-name> <var-value>true</var-value> </var> <var> <var-name>field-test[0]</var-name> <var-value>NOTNULL</var-value> </var> </field> <field property="dob" indexedListProperty="dependents" depends="requiredif,date"> <arg0 key="dependentlistForm.dob.label"/> <var> <var-name>field[0]</var-name> <var-value>lastName</var-value> </var> <var> <var-name>field-indexed[0]</var-name> <var-value>true</var-value> </var> <var> <var-name>field-test[0]</var-name> <var-value>NOTNULL</var-value> </var> </field> <field property="coverageType" indexedListProperty="dependents" depends="requiredif"> <arg0 key="dependentlistForm.coverageType.label"/> <var> <var-name>field[0]</var-name> <var-value>lastName</var-value> </var> <var> <var-name>field-indexed[0]</var-name> <var-value>true</var-value> </var> <var> <var-name>field-test[0]</var-name> <var-value>NOTNULL</var-value> </var> <var> <var-name>field[1]</var-name> <var-value>insureDependents</var-value> </var> <var> <var-name>field-test[1]</var-name> <var-value>EQUAL</var-value> </var> <var> <var-name>field-value[1]</var-name> <var-value>true</var-value> </var> <var> <var-name>field-join</var-name> <var-value>AND</var-value> </var> </field> </form> Apache Cocoon的例子 下面的例子是Apache Cocoon的教学程序中的文件。对id和name两个域进行验证。同时,这个文件定义了页面元素和数据库数据之间的绑定。下一节就要阐述这个问题。 <root> <parameter name="id" type="long" nullable="no"/> <parameter name="name" type="string" min-len="5" max-len="64"/> <constraint-set name="update"> <validate name="name"/> <validate name="id"/> </constraint-set> <constraint-set name="add"> <validate name="name"/> </constraint-set> <connection>personnel</connection> <table name="department"> <keys> <key param="id" dbcol="id" type="int" mode="manual"/> </keys> <values> <value param="name" dbcol="name" type="string"/> </values> </table> </root> Database Driven Page 正如上一节最后一个例子(Apache Cocoon)所示,很多web开发框架提供页面元素和数据库字段的直接绑定。 .NET 框架包含三个便于显示大量数据的控件:Repeater 控件、DataList 控件和 DataGrid 控件。这三个控件都使用相似的数据绑定过程,绑定到DataSet、SqlDataReader或DataView。下面的代码示例从.Net框架文档摘录,显示如何将 SQL 数据库查询返回的 DataSet 绑定到 DataGrid 控件。 <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <HTML> <script language="C#" runat="server"> protected void Page_Load(Object Src, EventArgs E) { // Create a connection to the "pubs" SQL database located on the // local computer. SqlConnection myConnection = new SqlConnection("server=localhost;" + "database=pubs;Trusted_Connection=Yes"); // Connect to the SQL database using a SQL SELECT query to get all // the data from the "Authors" table. SqlDataAdapter myCommand = new SqlDataAdapter("SELECT " + " * FROM Authors", myConnection); // Create and fill a DataSet. DataSet ds = new DataSet(); myCommand.Fill(ds); // Bind MyDataGrid to the DataSet. MyDataGrid is the ID for the // DataGrid control in the HTML section. DataView source = new DataView(ds.Tables[0]); MyDataGrid.DataSource = source ; MyDataGrid.DataBind(); } </script> <body> <%-- Display the DataGrid information in the body of the page. --%> <h3><font face="Verdana">Simple SELECT to a DataGrid Control </font></h3> <%-- Display the data in a DataGrid. --%> <ASP:DataGrid id="MyDataGrid" runat="server" Width="700" BackColor="#ccccff" BorderColor="black" ShowFooter="false" CellPadding=3 CellSpacing="0" Font-Name="Verdana" Font-Size="8pt" HeaderStyle-BackColor="#aaaadd" EnableViewState="false" /> </body> </HTML> 多语言支持 多语言支持策略基本上都采取一种类似于查多本字典的模式。先举一个类比例子来说明,比如,我们有英英字典,英汉字典,英德字典,英法字典,对于一个英文单词,每本字典都有对应语言的单词,满足不同语言的用户的需要。我们把要查的英文单词称为key,所有的字典称为资源文件resource file,查出来的对应语言的单词,就是应该显示给用户的内容。、 上述模式简单而常见,不再列出例子代码,下面只进行简单的说明。 .Net框架通过一个重要的资源管理类System.Resources.ResourceManager,来管理在应用程序中使用的不同特定于区域性的资源。调用方可使用 GetObject 和 GetString 两种方法访问特定区域性的资源。这两个方法的参数都包括一个key,和一个本地语言信息。.Net的资源文件后缀是DLL。 Apache Struts项目的类org.apache.struts.util.MessageResources的getMessage方法提供了类似的功能。Apache Struts项目提供了一个扩展的HTML Tag —— Message,也起着多语言支持、本地化的作用。Struts的资源文件后缀是properties,格式按照java properties文件的格式。 Apache Cocoon项目提供了一类称为i18n的Transformer,用来实现多语言支持。常用的标记如<i18n:text>和<i18n:param>。Cocoon的多语言支持策略和前面所说的一样,应用方法也类似,但是实现方式却不一样——Cocoon采用XSLT实现多语言支持。Cocoon的资源文件后缀是xml,格式按照xml格式。看来,把xml贯彻始终者,非Cocoon莫属。 Web开发框架中的架构模式比较(五) 发布日期:2003-3-30 发 布 者:51jsp.net 用户身份确认Authentication 和授权Authorization 当web用户访问web服务器上的受到保护的资源时,通常要经过两个步骤。(从.Net框架文档摘录) 1.用户身份确认Authentication 确保用户不是假冒的。应用程序获取用户的凭据(各种形式的标识,如用户名和密码)并通过某些授权机构验证那些凭据。如果这些凭据有效,则提交这些凭据的实体被视为经过身份验证的标识。 2.授权Authorization 通过对已验证身份授予或拒绝特定权限来限制访问权限。 ASP.Net和java web框架的资源保护策略都遵循这样的模型:对应于被保护的资源,定义一组角色,用户,和允许的操作。操作在java web框架中称为http-method,在ASP.Net中称为Verb,都表示HTTP GET,HTTP POST等HTTP方法。 根据servlet2.4规范,java web框架的网页的login form应该按照下例书写。注意,form的action属性的值应该为j_security_check。 <form method=”POST” action=”j_security_check”> <input type=”text” name=”j_username”> <input type=”password” name=”j_password”> </form> ASP.Net的服务器端配置文件web.config例子。(节录) 下面的例子从.Net框架文档中摘录出来。 <authentication mode="forms"> <forms forms="401kApp" loginurl="/login.aspx" decryptionkey="1!#$$*13^"> <credentials passwordFormat=SHA1> <user name="Kim" password="9611E4F94EC4972D5A537EA28C69F89AD28E5B36"/> <user name="John" password="BA7157A99DFE9DD70A94D89844A4B4993B10168F"/> </credentials> </forms> </authentication> … <authorization> <allow users="John" /> <deny users="*" /> </authorization> … <authorization> <allow verb="GET" users="*" /> <allow verb="POST" users="Kim" /> <deny verb="POST" users="*" /> </authorization> … Java web 框架的服务器端配置文件web.xml例子。 下例从servlet2.4规范中摘录。其中的< security-role >和< security-constraint >部分中定义了受保护资源对应的角色,用户,和允许的操作。 <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http:// java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version=”2.4”> <display-name>A Secure Application</display-name> <servlet> <servlet-name>catalog</servlet-name> <servlet-class>com.mycorp.CatalogServlet </servlet-class> <init-param> <param-name>catalog</param-name> <param-value>Spring</param-value> </init-param> <security-role-ref> <role-name>MGR</role-name> <!-- role name used in code --> <role-link>manager</role-link> </security-role-ref> </servlet> <security-role> <role-name>manager</role-name> </security-role> <servlet-mapping> <servlet-name>catalog</servlet-name> <url-pattern>/catalog/*</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>SalesInfo </web-resource-name> <url-pattern>/salesinfo/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL </transport-guarantee> </user-data-constraint> </security-constraint> </web-app> SOAP Web Service .Net框架和Apache Axis项目都提供了Web Service的SOAP实现。采用的基本模式如下。 通过XML序列化实现SOAP XML数据到应用程序对象的绑定;XML序列化(和反序列化)发生在服务端和客户段;XML数据和应用程序对象Object的映射规则为,Object映射为一个XML元素,Object的“属性”(property)成员映射为该XML元素的子元素。 Java和C# 都支持Reflection机制,能够在运行时判断Object的类型。但有些细微的差别:Java对象的“属性”(property)并不是一种类型,而是一种符合getXXX,setXXX形式的约定;C#对象的“属性”(property)是在类内部声明的一种类型;还有,C#支持Attribute,比如,[SoapElement]、[XmlElement]、[WebMethod]、[SoapRpcMethod]等属性。所以,C#对象的XML序列化定义更加严格一些。 另外,两种语言的集合类也有差别,对于某些特殊的集合类,如hashtable,会有不兼容的情况,所以,最好发送数组类型,以保证不同语言开发的SOAP Web Service能够相互使用。 SOAP支持几种数组类型,其中有两种数组类型 —— 多维数组和复合数组,这里说明一下。多维数组是指如 3 * 4 之类的3行4列的整齐数组,C# 语言支持这种多维数组,java语言不支持这种多维数组;复合数组是指数组的数组,即数组的元素也可以是属组,C# 语言和java语言都支持这种复合数组。不过,复合数组也可以用来表示多维数组,比如复合数组的元素个数为3,元素类型为大小为4的数组,就可以用来表示3 * 4 之类的3行4列的整齐数组。 |
2.Re:<下一代WEB开发模型> [Re: nothing] | Copy to clipboard |
Posted by: yanger Posted on: 2003-05-26 10:42 一个字,长 |
3.Re:<下一代WEB开发模型> [Re: nothing] | Copy to clipboard |
Posted by: floater Posted on: 2003-05-28 00:57 What's the point? I am totally lost, . |
Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1 客服电话 18559299278 客服信箱 714923@qq.com 客服QQ 714923 |