??xml version="1.0" encoding="utf-8" standalone="yes"?> 随着Java技术的不断发展Q它Ҏ(gu)市场q一步细分ؓ(f):针对企业|应用的J2EEQJava 2 Enterprise EditionQ、针Ҏ(gu)通PC应用的J2SEQJava 2 Standard EditionQ和针对嵌入式设备及(qing)消费cȝ(sh)器的J2MEQJava 2 Micro EditionQ三个版本。本文就Sun ONE的Java核心应用——J2SE/J2EE/J2ME作一些介l?/p>
J2EE技术应?
J2EE是Sun公司推出的一U全新概늚模型Q比传统的互联网应用E序模型更有优势?/p>
J2EE模型
J2EE的应用编E模型(J2EE BlueprintsQ提供了一U用于实施基于J2EE多层应用的文档和实例套g的体pL型,化了q项复杂的工作。它被开发h员用作设计和优化lgQ以便开发h员从{略上对开发工作进行分工?/p>
J2EE应用~程模型要求开发者将自己的工作分成两c:(x)商业逻辑和表C逻辑Q其余则ql资源自动处理,不必Z间层道q行~码。这P开发h员就能将更多的时间花在商业逻辑和表C逻辑上。对重视~短目周期的公司来_(d)q种转变深受Ƣ迎?/p>
J2EEq_
J2EEq_是运行J2EE应用的标准环境,由J2EE部v规范Q一套所有J2EEq_产品都必L持的标准Q、IETF标准集和CORBA标准l成。最新的J2EEq_q添加了JavaBeanlg模型。开发h员可以利用JavaBeanlg模型来自定义Javacd例,q可通过已定义的事g讉KJavacR?/p>
J2EE支持EJBQ因此开发h员可以执行多用户交易功能。当在J2EE服务器上q行ӞEnterprise JavaBeans应用逻辑分成可再利用和可扩展的代码段。Enterprise JavaBeansq不是新特征Q但是通过定义标准客户端和服务APIQJ2EE增强了它的能力和可移植性?/p>
EJB在服务器的一个容器内q行Q提供所有典型的中间层服务,如事务管理、安全、远E客戯接、生存周期管理和数据库连接缓册Ӏؓ(f)了让事务pȝ在存在EJB容器的情况下q行Q开发h员只需在部|描q文件中定义Beans的事务属性即可?/p>
J2EE通过定义一l标准的l构来实现它的优势,例如Q?/p>
1.J2EE Application Programming ModelQ是一U用于开发多层次、瘦型客L(fng)L(fng)序的标准设计模型Q?/p>
2. J2EE PlatformQ是一个标准的q_Q用来整合J2EE的应用程序,q指定一pd的接口和Ҏ(gu)Q?/p>
3. J2EE Compatibility Test SuiteQ是一套兼Ҏ(gu)试组Ӟ用来(g)品是否同J2EEq_兼容Q?/p>
4.J2EE Reference ImplementationQ用来示范J2EE的能力?/p>
J2EE服务?
Sun的J2EE服务器通过Java 命名和目录接口(JNDIQ、认证、HTTP?qing)与Enterprise JavaBeans兼容的能力,提供命名和目录服务。JNDI是Javaq_的一U标准扩展版Q向企业内的命名和目录服务提供具有Java功能的,带有l一接口的应用,包括LDAP?/p>
J2EE服务器还利用了Java Servlet技术。Java Servlet可以看作是运行在服务器上的一个小E序Q它向开发h员提供以lg为基创徏ZWeb应用的、独立于q_的方法。它不像利用CGI那样h性能局限。Java Servlet是一U扩展Web服务器功能的单技巧。由于它是用Java~写的,因而能够访问整个Java API库,也包括用于访问企业数据库的JDBC API?/p>
JSP是Java Servlet的一U扩展。Java Servlet提供开发和昄来自服务器的交互式Webc(din)如今JSP又有了进一步的改进Q它使得创徏和支持静态模板和动态内容相l合的HTML和XML面更加Ҏ(gu)?/p>
安全?
J2EEq_定义了一U标准的公开存取控制规则Q当E序在企业^C开发时已被程序师定义和解释了。J2EE也需要提供一个标准的注册机制Q以便应用程序不?x)将q些注册机制和逻辑相合,从而相同的工作执行于大量的不同环境中时ƈ不需要改变源代码。例如:(x)J2EE应用E序开发h员可以指定几个安全别,当用戯问数据时Q他们可写出代码来检查当前用h限的U别。在开发阶D,开发h员赋予多l用户适当的安全Q应用E序在执行限制操作之前能够容易的判断限制U?/p>
J2EE q_是Java技术企业应用的最?jng)_^収ͼ它可以让E序员迅速、快捷地开发和分布企业U应应用E序。以下便是它的相x术:(x) 1.Enterprise JavaBeans ArchitectureQ企业JavaBeans 定义了一个应用程序接口。它可以使程序员q速开发、发布和理跨^台的、基于组件的企业U应用程序?/p>
2.JavaServer PagesQJSP 技术提供了一U简单、快速的Ҏ(gu)来创建动态网c(din)通过它,可以快速地开发基于Web的应用程序,q且q些应用E序都是与^台无关的。因为JSP与ASP很相|所以熟(zhn)ASP的h学习(fn)它就很容易了?/p>
3.Java ServletQ提供了应用E序接口。通过它可以简单快速地开发ƈ扩展服务器功能。就发展势来看Q它?yu)来有可能取代CGI?/p>
4.J2EE ConnectorQ提供了一U标准结构来联接不同的企业信息^台?/p>
5.Java Naming and Directory Interface(JNDI)Q在Java q_与商业信息之_(d)JNDI提供了统一、无~的标准化连接。通过使用JNDIQ程序员可以在企业多命名与目录服务之间传送Java 应用E序?/p>
6.Java Interface Definition Language(JIDL),通过使用CORBAQ可以提供协同工作的能力。JIDL包括一个IDL-to-Java ~译器和支持IIOPQInternet Inter-Orb ProtocolQ的ORB?/p>
7.JDBC,几乎是ؓ(f)所有的数据库提供了l一的接口,同时可以创徏高工具和接口?/p>
8.Java Message Service(JMS)Q它几乎规范了所有企业消息服务Q如可靠查询、发布消息、订阅杂志等各种各样的PUSS/PULL技术的应用Qƈ且ؓ(f)它们提供了一个标准接口?/p>
9.Java Transaction API(JTA)Qؓ(f)分布式系l中可处理的应用E序规定了一个高U的理规范?/p>
10.JavaMail,JavaMail应用E序接口提供了一整套模拟邮gpȝ的抽象类。通过JavaMailQ可以创建邮件或消息应用E序?/p>
11.RMI-IIOP,使用它就可以只用Java 技术和Java RMI接口开发客h与服务器的远E接口?/p>
J2EE使用固定的文件格式捆l某个模块:(x)?ear文g捆绑J2EE应用E序Q用.jar捆绑Enterprise Bean。例如,一?ear文g包含一?xml文g作ؓ(f)其分布描qͼq包含一个或多个.jar?war文gQ一?jar文g除了包含它的分布描述外,q包含了作ؓ(f)Enterprise bean?class文g?/p>
J2EE应用E序的开发阶D分为四步:(x)1.Enterprise Bean创徏Q?.Web Component创徏Q?.J2EE应用E序装配Q?.J2EE应用E序分布。以下是J2EE兼容产品部分列表Q?/p>
BEA WebLogic Server 6.0、Borland App Server、HP Bluestone Total-e-Server、IBM WebSphere Application Server、IONA iPortal Application Server、iPlanet Application Server、Macromedia JRun Server、Oracle 9i Application Server、SilverStrean Application Server、Sybase EAServer、TogetherSoft ControlCenter、Java 2 SDK Enterprise Edition?/p>
J2ME技术的应用
J2MEQJava 2 Platform Micro EditionQ是为无U电(sh)子市场所设计的,包括JVM规范和API规范。其API规范是基于J2SEQJava 2 Standard Editon)的。J2ME 定义了一套合适的cd和虚拟机技术。这些技术可以用户、服务提供商和设备制造商通过物理Q有U)q接或无U连接,按照需要随时用丰富的应用E序?/p>
J2ME又被UCؓ(f)Java 2 微型版,被用在各种各样的消费电(sh)子品上Q例如智能卡、手机、PDA、电(sh)视机盒{方面。当然了QJ2ME也提供了Java语言一贯的Ҏ(gu),那就是跨q_和安全网l传输。它使用了一pd更小的包Q而且Javax.microedition.io 为J2SE包的子集。J2ME可以升到J2SE和J2EE?/p>
在J2ME出现之前Q我们更多接触到的是Java卡(Java CardQ、嵌入式JavaQEmbedded JavaQ和实时JavaQReal Time JavaQ等。其中Java卡是针对SIM卡、智能卡{设备而定制的最Java子集Q比J2MEq要,UL性也不强。嵌入式Java则针对特D用戯行配|Javacd和VMQVirtual MachineQ虚拟机Q。它对资源需求极,可运行在无图形用h口和|络的设备上Q可以添加用户专用的APIQ但是它?yu)无法移植。实时Java是由IBM领导的实时定制Java专家l负责实施的Q现在还在不断完善中。不q,从严格意义上来说Q它们都不是真正的J2ME?/p>
像其它版本一PJ2MEh很多Java技术特性,主要有:(x) 1.可以在各U支持Java的设备上q行Q?/p>
2.代码短小Q?/p>
3.充分利用Java语言的优势; 4.安全性好Q?/p>
5.用J2ME实现的应用可以方便地升到J2SE、J2EE?/p>
J2ME的配|和框架
Z支持用户和嵌入式市场提出的灵zL和可定制性要求,J2ME被设计得更加模块化和可羃攑。J2ME在设备原有的操作pȝ上徏造了3层Y件来实现q种要求Q?/p>
1.JVM层,q层Z宿主操作pȝQ按照某一UJ2ME的配|,实现了JVM?/p>
2.配置层,q层对于用户可见度要低一些,但对框架层非帔R要。它针对“水^”市场的需求,定义了Java虚拟机的最功能集和Javacd的最集合。在某种意义上,配置层定义了开发者在所有设备上都可以用JavaҎ(gu)和cd?#8220;最公分母”?/p>
3.框架层,q层对于用户和应用程序提供者来说是最常见的。它针对“垂直”市场的需求,定义了Java虚拟机的最功能集和Javacd的最集合。其框架是基于特定的配置层实现的。只要设备支持相同的框架层,针对特定框架层开发的应用E序可以移植到其它讑֤上。一个设备可以支持多个框架层?/p>
在J2ME讑֤中,JVM与配|层紧密相连Q它们体C每一c设备的基本功能。框架层针对不同的设备,在配|层的基上规定了附加的API。ؓ(f)了满不断更新的应用E序Q框架层可以扩充新的Java库类。在不远的将来,随着新设备的不断出现QJ2ME技术将提供范围q泛的框架层、配|层和VM。JCPQJava Community ProcessQ可以ؓ(f)客户和开发商提供规范。根据JCP的定义,J2ME目前的一U配|层?#8220;面向q接的设备配|?#8221;层(Connected Device ConfigurationQ,它采用典型的Java虚拟机技术。这U全功能的VM包含了基于台式机pȝ上的虚拟机的所有功能,适用于拥有至几兆字节内存的讑֤。对于无U设备和其它内存不的设备,J2ME采用“面向q接的受限设备配|?#8221;QCLDCQ技术?/p>
KVM是J2ME的核心特征。它是一个可UL性非帔R的JVMQ专用于内存、资源有限、能上网的设备,例如蜂窝?sh)话、寻呼机和个人组l器{。这些器件一般都含有16?2位的处理器,最?28KB内存。KVM能够被灵zd用到各种行业、各U类型的讑֤上,q能够适应q些讑֤的多样化所带来的问题,比如处理器的耗电(sh)量、内存的大小、设备和应用E序的特D功能等问题?/p>
CLDC技?
CLDC定义了目标Javaq_Q该q_Z型的、资源较?yu)的、内存仅?60?12K的设备。CLDC是由KVM和用在蜂H电(sh)话、数字品、双向寻呼机、个人组l器和家用电(sh)器等核心库类?qing)接口组成。用CLDC技术有很多优点Q?/p>
1.跨^収ͼq点保留了Java一贯的特点Q应用程序不?x)随着q_差异而生变化?/p>
2.动态性,q点也是很吸引h的,可以Ҏ(gu)需要下载自己喜Ƣ的应用E序和服务,q且可以和其它的CLDC讑֤通信?/p>
3.安全性,Java 本n的特炚w就了这一Ҏ(gu)?/p>
?J2SE相比QCLDC~少下列所说的特征Q?/p>
1.AWTQ抽象窗口开发包Q,Swing或其它图形库Q?/p>
2.用户定义c装载器Q?/p>
3.cd例的最l化Q?/p>
4.q引用Q?/p>
5.RMIQ?/p>
6.ReflectionQ映)?/p>
CLDC有四个包Qjava.lang、java.util、java.io和javax.microedition。除了javax.microedition包以外,其它的几个包都是J2SE包的核心子集。CLDC采用q些J2SEcdQ但是把其中一些在微型讑֤中用不到cR属性和Ҏ(gu)L了?/p>
J2ME定义两个配置:Connected Device Configuration(q接讑֤配置QCDC)和限制性更强的Connected Limited Device Configuration(有限q接讑֤配置QCLDC)?/p>
J2SE技术的应用
Java 2标准版是一U开发和部vq_Q提供了~写桌面、工作站应用E序所有必需的功能。J2SE软g是快速开发、部|关键Q务和企业应用E序的首选解x案。J2SE 1.4版本是基于Java跨^台技术和强有力的安全模块而开发的Q其最新的特征和功能极大地提高了Java语言的~性、灵zL、适用性,以及(qing)可靠性?/p>
J2SE 1.4 特点Q?
1.良好的计性能和羃放能力?/p>
J2SE 1.4版是一个快速开发和配置跨^台的企业U应用与服务的综合性^台。它提升了Java计算的性能与羃放能力,代表了Java技术的大跨步进展。有了J2SE 1.4版,企业可以通过更简易的步骤、花Ҏ(gu)的旉Q采用Java技术开发与配置要求更高的应用了。J2SE 1.4版在Java客户机应用方面得C重大性能提升。基于Swing的Java程序和应用E序在图形用L(fng)?GUI)的响应速度上也大有提高?/p>
2.跨^?/p>
J2SE 1.4版是一个具有综合性能的^収ͼ能一个完整的、可~放的高性能应用配置在Q何种cȝq_上?/p>
3.支持Web服务 J2SE 1.4版与以前各J2SE版全面兼宏VJ2SE 1.4版对SSL、LDAP和CORBA{业界标准技术也l予支持Q因此保证了在不同^台、系l和环境间的互操作能力。J2SE 1.4版支持XML技术和一整套安全服务Q因此ؓ(f)Z各类标准的可互操作应用与服务的创建奠定了重要基础。有了J2SE 1.4版与Java Web Services Developer Pack的结合,开发商p创徏、测试和配置Web服务了?/p>
4.完整?/p>
J2SE 1.4版还是一个完整的开发环境。开发商可基于这一环境创徏功能丰富的交互式应用。这些应用可以配|在Mq_上。J2SE 1.4h新的GUI控制功能、快速的Java 2DT囑Ş功能、支持国际化与本地化扩展和新的配|选项Qƈ对Windows XP提供扩展支持?/p>
MQJ2SE 1.4版是多种不同风格软g的开发基Q包括客L(fng)Java程序和应用E序Q以?qing)独立的服务器应用程序等。J2SE 1.4版还是J2ME的基Q是J2EE执行E序的推动力?/p>
Java之所以能够发展得很快Q是因ؓ(f)互联|的发展非常快。Java可以和浏览器l合在一P因而很自然地在桌面pȝ得到q泛应用。从计算的结构来看,Java主要分三大类Q第一是服务器端,q里有了J2EE企业版;W二是桌面PCQ这一cȝ的是J2SE标准?W三是掌上?sh)脑、移动设备,用的都是J2ME。但是,大部分非企业UY件还是在J2SE上开发的比较多。首先,q是因ؓ(f)很多的应用Y仉是在J2SE上开发的Q其ơ,J2SE是和J2EE兼容的,企业版是在标准版上的扩充Q在J2SE的版本上开发的软gQ拿C业的q_上是一样可以运行的Q再ơ,一般开发还是在J2SE的环境上Q只是说J2ME提供微型版的一个环境。在J2SE上虚拟出一个环境,开发出来的应用软g是可以拿到微型版上运行的?/p>
ArgoUML 使用java~写的开源UML产品Q功能比较全。最受欢q的UML建模工具? Alma Alma是一个Y件徏模分析的工作q_Q它d几种不同的源代码Q帮你设计面向对像的模型Q修改结构和源代码,输出新的源代码、文档和图表?/p>
UMLet UMLet是一个开放源代码轻量UUML建模工具。UMLet能够让你快速徏模,q且能够导出各种格式SVG, JPG, PDF and LaTeX-friendly EPS?/p>
UML/Dot UML/Dotq个目从Java源代码或字节码中生成UMLcR用GraphViz Dot生成图表。用户可以完全控制处理过E,可以隐藏或显CZQ意提取的元素。需要:(x)JAVA v1.4 或更高版本,GraphViz? JUG Java UML Generator 是用于从JavacL件自动生成UMLcd的工兗最初设计ؓ(f)一个命令行工具Q将.class/.jar文g转换?emf/.eps文gQ现在它提供了一个可视化环境? Violet Violet是一U轻量的UML建模工具。易学易?可以快速绘制类图、对象图、时序图和状态图 跨^?支持中文 源码开? UMLGraph UMLGraph支持说明性规U(Declarative Specification),cd(Class Diagram) ,序?Sequence Diagrams). Fujaba Tool Suite Fujaba Tool Suitel合UMLcd与UML行ؓ(f)视图来提供一个强?易于使用,而且是整齐均U的pȝ设计与规范语a. 而且Fujaba Tool Suiteq支持从整个pȝ设计生成Java源代码从完美地实C一个可执行的模型.同样也支持相反操作,因此源代码可以被解析q被表现在UML中. UniMod UniMod是Executable UML思想的实现。UniMod是以Eclipse插g形式存在。可以通过UniMod提供的一个在UDemo了解更多的详l资料?/p>
Taylor MDA Taylor MDA是一个基于Eclipse的UML建模工具。它专注于EJB3企业应用E序的生成。Taylor MDA当前支持生成Q?/p>
StarUML StarUML是一个运行在Win32上快速,灉|Q可扩展Q功能强大的UML/MDAq_。开源项目StarUML的目的是提供一个可以用来代替知名商业UML工具比如Rational Rose,Together{的建模工具和^台?/p>
Quick Sequence Diagram Editor q个单的工具能够利用对像与信息的描述文本来生成UML时序图。它采用Java5开发ƈ打包成一个可执行的Jar文g?/p>
TinyUML TinyUML是一个能够帮助你快速和L地绘制UML2囄开源工兗采用Java5开发?/p>
Papyrus Papyrus是一个基于Eclipseq_UML2建模工具。遵从Eclipse UML2、支持由O(jin)MG规定的UML2标准和DI2 QDiagram InterchangeQ标准、Papyrus的整个架构是可扩展的允许用户增加新的图样QdiagramQ和新的代码生成器等、支持UML2 Profile开发、嵌套Profile支持{?/p>
当前主要有两个版本,struts 1.0 release ?struts 1.1 beta 3。Struts 1.0 ?.1差别很大Q主要有两点Q?/p>
管struts 1.0 是正式发布版Q但是结构已l老化Q功能也已经固化。所以我们的Framework不选用struts 1.0, 而选用 struts 1.1?/p>
Ҏ(gu)a(chn)pache官方|站的说法,struts几乎支持所有的servlet containers, 下面是几U主要的servlet containers Servlet Container 版本 我们公司目前目中用较多的应用服务器是iPlanet Application Server, Tomcat。Struts 1.1 在这两个应用服务器下已经配置通过?/p>
Tomcat 与strutsl合的很好,只需要将xxx.war 攑ֈ webapp 目录下,启动Tomcat 卛_Q不需要其他额外的配置?/p>
iPlanet 配置复杂一些,主要原因是xml parser 版本不一_(d)和struts 相关cM能加载。具体的配置说明误《如何在 iAS 6.x 中配|Struts 1.1 beta x》?/p>
在其他的应用服务器上Q还没有试struts, 今后Ҏ(gu)目需要会(x)作进一步的研究?/p>
struts framework是MVC 模式的体玎ͼ下面分别从模型、视图、控制来看看struts的体pȝ构(ArchitectureQ。下图显CZstruts framework的体pȝ构响应客戯求时Q各个部分工作的原理?/p>
主要由JSP建立Qstruts自n包含了一l可扩展的自定义标签库(TagLibQ,可以化创建用L(fng)面的q程。目前包括:(x)Bean TagsQHTML TagsQLogic TagsQNested TagsQTemplate Tags?/p>
模型主要是表CZ个系l的状态(有时候,改变pȝ状态的业务逻辑操作也也划分到模型中Q。在Struts中,pȝ的状态主要有ActiomForm Bean体现Q一般情况下Q这些状态是非持久性的。如果需要将q些状态{化ؓ(f)持久性数据存储,Struts本n也提供了Utitle包,可以方便的与数据库操作?/p>
在Struts framework中, Controller主要是ActionServletQ但是对于业务逻辑的操作则主要由Action、ActionMapping、ActionForwardq几个组件协调完成。其中,Action扮演了真正的业务逻辑的实现者,而ActionMapping和ActionForward则指定了不同业务逻辑或流E的q行方向?/p>
框架中所使用的组Ӟ(x) Struts-config.xml集中了所有页面的D定义。对于WEB目Q通过配置文g可迅速把握其脉络Q这不管是对于前期的开发,q是后期的维护或升都是方便的。掌握Struts-config.xml是掌握Struts的关键所在?/p>
在struts的早先版本中Q只有一个struts配置文gstruts-config.xml。但是,对大型项目来_(d)使用和修改这个配|文Ӟ?x)成为瓶颈。在struts1.1中,支持sub-Application Q可以定义多个配|文件协同工作?/p>
通过struts配置文gstruts-config.xml struts各个lg联系在一赗在struts-config.xml 中可以定义下面内容:(x) 全局转发用来在JSP之间创建逻辑名称映射。全局转发的例子:(x) <forwardname="logoff"path="/logoff.do"/> <forwardname="logon"path="/logon.jsp"/> <forwardname="registration"path="/registration.jsp"/> <forwardname="success"path="/mainMenu.jsp"/> </global-forwards> ActionMapping对象帮助q行框架内部的流E控Ӟ它们可将hURI映射到Actionc?q且ActioncMActionForm bean相关联。ActionServlet在内部用这些映,q将控制转移到特定Actioncȝ实例。所有ActioncM用perform()或者execute()Ҏ(gu)实现特定应用E序代码Q返回一个ActionForward对象Q其中包括响应{发的目标面名称。例如:(x) <actionpath="/logon" type="org.apache.struts.webapp.example.LogonAction" name="logonForm" scope="session" input="logon"> </action> <forward name="failure" path="/error.jsp"/> <forward name="success" path="/index.jsp"/> </ action-mappings> 属?/strong> 描述 Path Actioncȝ相对路径 Name 与本操作兌的Action bean的名U?/p>
Type q接到本映射的Actioncȝ全称Q可有包名) Scope ActionForm bean的作用域Q请求或?x)话Q?/p>
Prefix 用来匚wh参数与bean属性的前缀 Suffix 用来匚wh参数与bean属性的后缀 attribute 作用域名U?/p>
className ActionMapping对象的类的完全限定名默认的类是org.apache.struts.action.ActionMapping input 输入表单的\径,指向bean发生输入错误必须q回的控?/p>
unknown 设ؓ(f)trueQ操作将被作为所有没有定义的ActionMapping的URI的默认操?/p>
validate 讄为trueQ则在调用Action对象上的perform()Ҏ(gu)前,ActionServlet调用ActionForm bean的validate()Ҏ(gu)来进行输入检?/p>
通过<forward>元素Q可以定义资源的逻辑名称Q该资源是Actioncȝ响应要{发的目标?/p>
ActionServlet使用ActionForm来保存请求的参数Q这些bean的属性名UCHTTPh参数中的名称相对应,控制器将h参数传递到ActionForm bean的实例,然后这个实例传送到ActioncR例子:(x) beans > <form bean name="bookForm" type="BookForm"/> </form beans> 属?/strong> 描述 Id ID className ActionForm bean的完全限定名Q默认值是org.apache.struts.action.ActionFormBean Name 表单bean在相关作用域的名Uͼq个属性用来将bean与ActionMappingq行兌 Type cȝ完全限定?/p>
例子Q?/p>
<data-source> <set-property property="autoCommit" value="false"/> <set-property property="description" value="Example Data Source Configuration"/> <set-property property="driverClass" value="org.postgresql.Driver"/> <set-property property="maxCount" value="4"/> <set-property property="minCount" value="2"/> <set-property property="password" value="mypassword"/> <set-property property="url" value="jdbc:postgresql://localhost/mydatabase"/> <set-property property="user" value="myusername"/> </data-source> </data-sources> 通过指定关键字名UͼActioncd以访问数据源Q比如:(x) javax.sql.DataSource ds = servlet.findDataSource(“conPool”); javax.sql.Connection con = ds.getConnection(); struts 标记库包?U类型的标记Q分别是Q?/p>
Struts提供了功能强大的TaglibQ充分用这些TagQ能最大限度的发挥Struts的作用?/p>
׃标记库功能强大,所以掌握它需要花费一定的旉。目前我们可以先?struts-html taglib 学vQ主要精力还是要先放在理解掌握strutsD功能上?/p>
文档《struts 标记库》可以帮助学?fn)掌握struts taglib. Camino 是基?struts framework的可视化建模工具。用camino 可以实现快速设计和开发,主要特点有:(x) 目前Camino的版本有2.05 ?3.0, 可以下蝲试用版。Camino 自带了帮助文档,可以方便学习(fn)Camino?/p>
Struts 1.1 beta 3 的包中包含了几个example, 可以帮助学习(fn)struts?/p>
在Tomcat 4.1.18q行环境下,只需要将 xxx.war 文g攑ֈwebapps 目录下,启动Tomcat 卛_?/p>
从struts-example 开始学?fn),熟读struts-config.xml, jsp, ?java 源码?/p>
Eclipse 是由IBM支持的开发源码的IDE, 目前的最新版本是2.1。与Netbeans, JBuilder相比Q由以下特点Q?/p>
目前Q每个项目用的开发工具都不同Q有JBuilder, Netbeans{。从长远考虑应该采用开发源码的IDE, 不存在盗版问题。现在开发源码的IDE有Netbeans, Eclipse两大阵营Q分别由Sun ?IBM支持。综合上面的EclipseҎ(gu),我推荐统一使用Eclipse?/p>
struts 官方|站Qhttp://jakarta.apache.org/struts struts resource : http://jakarta.apache.org/struts/resources/index.html Camino |站Qhttp://www.scioworks.com/index.html 其他|站Qhttp://husted.com/struts/ http://struts.application-servers.com/main.html http://www.synthis.com/products/architectures/struts/index.jsp 《struts框架详细介绍?- ppt 文档Q描qCstruts 框架 《struts-intro? ppt 文档Q其中的struts D程N常好?/p>
《Using Struts?- ppt 文档Q概qCstruts 框架和组?/p>
《如何在 iAS 6.x 中配|Struts 1.1 beta x? 讲述在iPlanet 6.x 如何配置 struts 1.1 《Struts标记库?- 详细介绍了struts taglib的?/p>
《struts turorial?- 一个网上购书的CZQ详l讲解了struts使用步骤
随着Internet|络的迅速发展,Z互联|的企业应用要求软gq_h开放性、分布性和q_无关性。于是就相出现了RPC/COM/CORBA{技术,但这些技术在实际应用中存在着许多不和局限。它们的特定协议难以通过防火墙,因而不适于Web上的应用开发。ؓ(f)了进一步开发基于Web的应用,出现了Sun公司的Sun ONEQOpen Net Environment 开发网l环境)和Microsoft公司?NET{Web 服务技术体pR?br />
Sun ONE体系l构以Java语言为核心,包括J2SE/J2EE/J2ME和一pd的标准、技术及(qing)协议。它包括Sun独有的iPlanet软gpdQ其中有在市Z受欢q的LDAP目录服务器YӞ以及(qing)Forte for Java——便于在M环境下书写Java 语言的Y件工兗我们很Ҏ(gu)p从网上免费获得和使用包括Java 集成开发环境、Java数据库和中间ӞApplication ServerQ服务器{品,以及(qing)它们的源代码。Sun ONE更接q或能满互联网在智能化Web服务斚w对分布性、开发性和q_无关性的要求?
]]>
]]>1.1 Struts 1.0 ?.1版本
1.2支持struts的应用服务器
iPlanet Application Server
6.0sp2 or higher, 6.5
Tomcat
3.2.x, 4.0 or higher
Weblogic
6.0 or higher
Websphere
3.5 or higher
Orion
1.0 or higher
Resin
1.2 or higher
JRun
3.0 or higher
1.3配置说明
struts框架
2.1 struts 体系l构
Struts体系l构
2.1.1 从视图角度(ViewQ?/strong>
2.1.2从模型角度(ModelQ?/strong>
2.1.3 从控制器角度QControllerQ?/strong>
2.2 struts 的组?/strong>
ActionServlet
控制?/strong>
ActionClass
包含事务逻辑
ActionForm
昄模块数据
ActionMapping
帮助控制器将h映射到操?/strong>
ActionForward
用来指示操作转移的对?/strong>
ActionError
用来存储和回攉?/strong>
Struts标记?/strong>
可以减轻开发显C层ơ的工作
2.3 struts 配置文g
2.3.1 配置全局转发
<global-forwards>
属?/strong>
描述
Name
全局转发的名?/td>
Path
与目标URL的相对\?/td>
2.3.2 配置ActionMapping
<action-mappings>
属?/strong>
描述
Id
ID
ClassName
ActionForwardcȝ完全限定名,默认是org.apache.struts.action.ActionForward
Name
操作c访问ActionForward时所用的逻辑?/td>
Path
响应转发的目标资源的路径
redirect
若设|ؓ(f)trueQ则ActionServlet使用sendRedirect()Ҏ(gu)来{发资?/td>
2.3.3 配置ActionForm Bean
<form
2.3.4 配置JDBC数据?/strong>
<data-sources>
属?/strong>
描述
description
数据源的描述
autoCommit
数据源创建的q接所使用的默认自动更新数据库模式
driverClass
数据源所使用的类Q用来显CJDBC驱动E序接口
loginTimeout
数据库登陆时间的限制Q以Uؓ(f)单位
maxCount
最多能建立的连接数?/td>
minCount
要创建的最连接数?/td>
password
数据库访问的密码
readOnly
创徏只读的连?/td>
User
讉K数据库的用户?/td>
url
JDBC的URL
struts标记?/strong>
可视化设计工具和代码生成器Camino
Struts example
Web应用E序
描述
Struts-blank.war
一个简单的web应用E序
Struts-documentation.war
包含struts站点上所有struts文档
Struts-example.war
Struts很多Ҏ(gu)的C
Struts-exercisetaglib.war
主要用于对自定义标签库进行增加而用的试,但也可以C如何使用struts标记
Struts-template.war
包含struts模板标记的介l和范例
Struts-upload.war
一个简单的例子Q示范如何用struts框架上传文g
6、统一的IDE工具Q?eclipse
7、参考资?/strong>
]]>
<HTML>
<HEAD>
<TITLE>合同甌</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<SCRIPT LANGUAGE = JavaScript>
/** Define object Dsy 构造器
fieldValues - 三个表单域的名称, 可以通过 request.getParameter(xxx) 取?br>defalutOptions - 默认选项
*/
function Dsy(fieldValues, defalutOptions){
this.Items = {};
this.defalutOptions = defalutOptions;// 默认选项
this.fieldValues = fieldValues;// 三个表单域的名称
}
Dsy.prototype.add = function(id, iArray){
this.Items[id] = iArray;
}Dsy.prototype.Exists = function(id){
if (typeof(this.Items[id]) == "undefined")
return false;
return true;
};Dsy.prototype.setup = function() {
this.bean_change(0);
}// This prototype method added by BeanSoft Studio
Dsy.prototype.bean_change = function(v){
var str = "0";
for (i = 0; i < v; i++){
str += ("_" + (document.getElementById(this.fieldValues[i]).selectedIndex - 1));
};var ss = document.getElementById(this.fieldValues[v]);
// Avoid a null exception
if(ss == null) return;with(ss){
length = 0;
options[0] = new Option(this.defalutOptions[v], this.defalutOptions[v]);
if (v && document.getElementById(this.fieldValues[v - 1]).selectedIndex > 0 || !v){
if (this.Exists(str)){
array = this.Items[str];
for (i = 0; i < array.length; i++)
options[length] = new Option(array[i], array[i]);
if (v)
options[1].selected = true;
}
}if (++v < s.length){
this.bean_change(v);
}
}
}function change(v){
dsy.bean_change(v);// Call test prototype
}// Write form data string, 输出表单脚本代码
// dsy, object name
// varName, 变量?br> function toString(dsy, varName) {
var str = "";
for(i = 0; i < dsy.fieldValues.length; i++) {
str += "<select id=\"" + dsy.fieldValues[i] + "\" onChange=\"" + varName + ".bean_change(" + (i + 1)
+ ");\"></select>\r\n";
}
str += "<br/>";
return str;
}// W一个对?br> var dsy = new Dsy(["s1", "s2", "s3"], ["销售方名称", "销售方联系?, "联系?sh)?]);
var dsy1 = new Dsy(["s4", "s5", "s6"], ["最l用户名U?, "最l用戯pMh", "联系?sh)?]);
var dsy2 = new Dsy(s = ["s7", "s8", "s9"], ["厂商", "厂商销?, "联系?sh)?]);// 填入数据, 重复的代?br> dsy.add("0", ["单位1", "单位2"]);
dsy.add("0_0", ["单位1联系人_1", "单位1联系人_2"]);
dsy.add("0_0_0", ["单位1联系人_1联系?sh)?]);
dsy.add("0_0_1", ["单位1联系人_2联系?sh)?]);dsy.add("0_1", ["单位2联系人_1", "单位2联系人_2"]);
dsy.add("0_1_0", ["单位2联系人_1联系?sh)?]);
dsy.add("0_1_1", ["单位2联系人_2联系?sh)?]);dsy1.add("0", ["最l用?", "最l用?"]);
dsy1.add("0_0", ["最l用?_联系?", "最l用?_联系?"]);
dsy1.add("0_0_0", ["最l用?_联系?_?sh)?]);
dsy1.add("0_0_1", ["最l用?_联系?_?sh)?]);dsy1.add("0_1", ["最l用?_联系?", "最l用?_联系?"]);
dsy1.add("0_1_0", ["最l用?_联系?_?sh)?]);
dsy1.add("0_1_1", ["最l用?_联系?_?sh)?]);dsy2.add("0", ["BEA", "Horizon"]);
dsy2.add("0_0", ["张学?, "BeanSoft"]);
dsy2.add("0_0_0", ["1234567890"]);
dsy2.add("0_0_1", ["beansoft@126.com"]);dsy2.add("0_1", ["AAA", "BBB"]);
dsy2.add("0_1_0", ["AAA_99999"]);
dsy2.add("0_1_1", ["bbb_88888"]);function setup(){ // Initialize the object
dsy.setup(); //依次调用 setup
dsy1.setup();
dsy2.setup();
}function prints1(){
alert(document.frm.s1.value + " " + document.frm.s2.value + " " + document.frm.s3.value +"\r\n");
}//isNaN()(g)查运结?nbsp; http://tech.ccidnet.com/pub/article/c1115_a120997_p1.html
</SCRIPT>
</head>
<body bgcolor="#E0E0E0" onload="setup()">
多兌菜单Q?br><form name="frm"><!-- 方式1: 手工输出 HTML 代码, 便于排版
<select id="s1" onChange="dsy.bean_change(1);"></select>
<select id="s2" onChange="dsy.bean_change(2);"></select>
<select id="s3" onChange="dsy.bean_change(3);"></select>
<br>
<br>
<br>
<select id="s4" onChange="dsy1.bean_change(1);"></select>
<select id="s5" onChange="dsy1.bean_change(2);"></select>
<select id="s6" onChange="dsy1.bean_change(3);"></select>
<br>
<br>
<br>
<select id="s7" onChange="dsy2.bean_change(1);"></select>
<select id="s8" onChange="dsy2.bean_change(2);"></select>
<select id="s9" onChange="dsy2.bean_change(3);"></select>
-->
<SCRIPT LANGUAGE="JavaScript">
<!--
// 方式2: 脚本输出表单 HTML 代码, 代码和上面注释掉的类?br>document.write(toString(dsy, "dsy"));
document.write(toString(dsy1, "dsy1"));
document.write(toString(dsy2, "dsy2"));
//-->
</SCRIPT><input type=button name=b1 value="监测" onclick="prints1()">
</form>
</body>
</html>
/* * WebFXCookie class */ function WebFXCookie() { if (document.cookie.length) { this.cookies = ' ' + document.cookie; } } WebFXCookie.prototype.setCookie = function (key, value) { document.cookie = key + "=" + escape(value); } WebFXCookie.prototype.getCookie = function (key) { if (this.cookies) { var start = this.cookies.indexOf(' ' + key + '='); if (start == -1) { returnnull; } var end = this.cookies.indexOf(";", start); if (end == -1) { end = this.cookies.length; } end -= start; var cookie = this.cookies.substr(start,end); return unescape(cookie.substr(cookie.indexOf('=') + 1, cookie.length - cookie.indexOf('=') + 1)); } else { returnnull; } } function getCookieVal (offset) { var endstr=document.cookie.indexOf (";",offset);if (endstr==-1) endstr=document.cookie.length;return unescape(document.cookie.substring(offset, endstr)); } function GetCookie (name) { var arg=name+"=";var alen=arg.length;var clen=document.cookie.length;var i = 0;while (i<clen) { var j=i+alen;if (document.cookie.substring(i,j)==arg) return getCookieVal (j);i = document.cookie.indexOf(" ",i)+1;if (i==0) break; } returnnull; } function DeleteCookie (name) { var exp=new Date(); exp.setTime (exp.getTime()-1); var cval=GetCookie (name); document.cookie=name+"="+cval+"; expires="+exp.toGMTString(); }
BeanSoft(刘长? 2007q?1?
关于q个问题, 比较复杂的说. 不过我希望通过例子来解释会(x)方便理解一?
假设有一个非常危险的d, 是九(ji)M? 需要你揣着炸药包从北^开车走高速\q保定去矛_庄把鬼子的碉堡给怺. 注意: q个d十分艰巨, 有可能半路炸药爆? 所以出发前你需要苦l?0元一本的<<铁布?gt;>, q需要立遗嘱交代一下后? 下面是\U图:
L路线: 北^ ==> 高速\收费站入?都有警察和警? A ==> 保定收费?B ==> 矛_庄收费站 C ==> 炸碉?D ==> 转R(刚才的R已经炸没? E =>
回来路线: 矛_庄收费站 ==> 保定收费?==> 高速\收费站出?都有警察和警? A ==> 安全回到北^ G
那么我们先简介可能发生的情况. A Ҏ(gu)可能被警察和警犬发现, 所以你只能被扭送回北^. 即不被发现, q可能出现收Ҏ(gu)发现10个现大洋一个\口的买\钱没?! ? 只能又回M. q有最惨的: 高速\入口写着: 对不? 到石家庄的\U因为施工不? 只好回家{着?
CB和C你可能还?x)被人发现带了炸药? 或者发C路费带? 极有可能又被扭送回北^, 注意已经在半道了, 是不?x)让你l到矛_庄的, 所以你?x)被从R上逮下? 然后转到警R上带回来! 也就是从 B 或?C 直接q回.
好了, 最x况就是你怺堡, 也成功的q回? 然后你可以开心的?lt;<铁布?gt;>扔了, 然后宣告遗嘱作废.
OK, 以上q程, 是qo(h)器和监听器的真实案例.
那么炸碉堡这个Q? q当于要调?JSP 或?Servlet 来获得执行结?炸碉?D ). 在执行之前你需要做一些准备工? 相当于要写一?br />监听?com.allanlxf.ums.web.ServiceListener
在里面你可以做一些事情例如初始化资源, 例如上文的苦l?lt;<铁布?gt;>, 立遗? q个相当于代码中?
public void contextInitialized(ServletContextEvent sce) q样一个初始化事g.
那么在整个Q务完成之? q些事情你就要考虑应该作废? 所以需?br />public void contextDestroyed(ServletContextEvent sce) q样一个销毁事? 例如?lt;<铁布?gt;>扔了, 然后宣告遗嘱作废, 也就是收回资?
那么qo(h)器在哪里? 它位于Q务的 A B C ? 注意是双向\E都?x)经q的. 也就是请求和响应都会(x)l过. 但是qo(h)器也?x)检查不同的情况, 例如 A 点实际上有两个过滤功? 查炸药包和收买\? q就相当于配|了:
*
*
*
两个qo(h)功能都要(g)? 如果成功了怎么办呢? ?x)l让你走下一个\? 注意不是让你直接成功. 也就是代?
if(session.getAttribute("user") != null || path.equals("/login"))//若用户已l登录ƈ且当前\径仍然停留在d面 {
chain.doFilter(request, response);//l箋C面的qo(h)器或者Q?不保证最lQ? 因ؓ(f)下个qo(h)器也可能让你回来)
只有当走?C 点的时? 下一步才是执行了最l的d: 执行JSP或者Servlet.
}
反过来怎么? 把你扭送上警R, q回! q样你连路口 B C 和最lQ务都无法讉K? 也就是不?x)让你访问下一个过滤器和执行最l的 JSP 或?Serlvet, 可以选择直接q回, 或者放警R上带回去.
{
return;// 直接q回
或?response.sendRedirect(request.getContextPath() + "/login.jsp");//则扭送上警R, q回到警察局
}
那么?E 点发生了什? 也就是你可能替换掉了原来?response 对象, 也就是换? q意味着你可以在qo(h)器里U下修改h和响应对?
虽然已经不那么抽象了, 但是要理解可能还是需要耐心体会(x)?
=====================================================================
? 原始问题
1.L(fng)下面一D代码和其注?
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class SessionFilter extends HttpFilter
{
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException
{
String path = request.getServletPath();//取得该servlet的\径名U?
path = path.substring(0, path.indexOf(".")); //获得路径?之前的部?
HttpSession session = request.getSession();//从请求中取得session为得是从session中读取用h否登录的标志?
if(session.getAttribute("user") != null || path.equals("/login"))//若用户已l登录ƈ且当前\径仍然停留在d面
{
* chain.doFilter(request, response);//则将当前滤镜加入到o(h)镜链条当?
}else//若用户尚未成功登?
{
response.sendRedirect(request.getContextPath() + "/login.jsp");//则用请求重定向转到d面
}
}
}
/*
* 该Filter滤镜cLqo(h)的是用户在浏览器中输入的
* 当前web application的访问\?通过判断用户?
* 否成功登录而决定是否对讉K路径加以限止
* 在该web application的web.xml配置文g中ؓ(f)
* 该filte滤镜做了相应配置
*/
请问: 上面代码FilterChain对象盛装的是Filter对象, 可它是怎么工作的啊?
?L(fng)语句是何用意?不是qo(h)路径? Z么要请求与响应加入?
2.L(fng)下面一D代?
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public abstract class HttpFilter implements Filter
{
private FilterConfig config;
public void init(FilterConfig config) throws ServletException
{
this.config = config;
init();
}
public void init() throws ServletException
{
}
public String getInitParameter(String name)
{
return config.getInitParameter(name);
}
public ServletContext getServletContext()
{
return config.getServletContext();
}
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException
{
doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);
}
public abstract void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException;
public void destroy()
{
}
}
请问: 该类p样写了一?没有包含M行ؓ(f),它如何完成过滤工作啊?
3.L(fng)下面代码:
package com.allanlxf.ums.web;
import javax.servlet.*;
//import javax.servlet.http.*;
import com.allanlxf.ums.service.SystemService;
import com.allanlxf.ums.service.StudentService;
public class ServiceListener implements ServletContextListener
{
public void contextInitialized(ServletContextEvent sce)
{
ServletContext application = sce.getServletContext();
StudentService service = new StudentService();
application.setAttribute("studentService", service);
SystemService systemService = new SystemService();
application.setAttribute("systemService", systemService);
}
public void contextDestroyed(ServletContextEvent sce)
{
}
}
/*
*本类是该web application的监听器c?在该cM,
*两个无为本pȝ提供服务的两个对象写入到?
*application隐含对象?q样保证在该pȝ的Q?
*地方都能够取得这两个服务cd象的引用)
*在本pȝ的web.xml文g中对该监听器做了配置
*/
请问: Z么要服务类对象写入到程序上下文中呢,直接创徏不也一样吗?
监听器只有这L(fng)功能?是否q有其它功能?
3.L(fng)下面的配|文件内?
*
*
*
请问: ?L(fng)三项是什么意?
当初老师讲的时?许多基本的原则原理尚不清?q些Ҏ(gu)没有听明?当然,老师也未l讲,只说?x)用卛_, 可是若不能明白其本质,用也只能用这一点儿, 怎么成呢, 希望(zhn)能够比较详(zhn)的讲一? thank you very much!
|
1?#8220;No bean found under attribute key XXX”
在struts-config.xml里定义了一个ActionFormQ但type属性指定的cM存在Qtype属性的值应该是Formcȝ全名。或者是Q在Action的定义中Qname或attribute属性指定的ActionForm不存在?
2?#8220;Cannot find bean XXX in any scope”
在Action里一般会(x)request.setAttribute()一些对象,然后在{向的jsp文g里(用tag或request.getAttribute()Ҏ(gu)Q得到这些对象ƈ昄出来。这个异常是说jsp要得C个对象,但前面的Action里ƈ没有对象设|到requestQ也可以是session、servletContextQ里?
可能是名字错了,h查jsp里的tag的一般是name属性,或getAttribute()Ҏ(gu)的参数|或者是Action逻辑有问题没有执行setAttribute()Ҏ(gu)先转向了?
q有另外一个可能,Ua(b)是jsp文g的问题,例如?x)指定一个id|然后在@环里使用q个g为name的|如果q两个g同,也会(x)出现此异常。(都是一个道理,request里没有对应的对象。)
3?#8220;Missing message for key "XXX"”
~少所需的资源,(g)查ApplicationResources.properties文g里是否有jsp文g里需要的资源Q例如:(x)
q行代码?x)找msg.name.prompt资源Q如果AppliationResources.properties里没有这个资源就?x)出现本异常。在使用多模块时Q要注意在模块的struts-config-xxx.xml里指定要使用的资源文件名Uͼ否则当然什么资源也找不刎ͼq也是一个很Ҏ(gu)犯的错误?
4?#8220;No getter method for property XXX of bean teacher”
q条异常信息说得很明白,jsp里要取一个bean的属性出来,但这个beanq没有这个属性。你应该(g)查jsp中某个标{property属性的倹{例如下面代码中的cade应该改ؓ(f)code才对Q?
5?#8220;Cannot find ActionMappings or ActionFormBeans collection”
待解冟?
6?#8220;Cannot retrieve mapping for action XXX”
?jsp的标{N指定action='/XXX'Q但q个Actionq未在struts-config.xml里设|过?
7、HTTP Status 404 - /xxx/xxx.jsp
Forward的path属性指向的jsp面不存在,h查\径和模块Q对于同一模块中的Action转向Qpath中不应包含模块名Q模块间转向Q记住用contextRelative="true"?
8、没有Q何异怿息,昄I白面
可能是Action里用的forward与struts-config.xml里定义的forward名称不匹配?
9?#8220;The element type "XXX" must be terminated by the matching end-tag "XXX".”
q个是struts-config.xml文g的格式错误,仔细(g)查它是否是良构的xml文gQ关于xml文g的格式这里就不赘qC?
10?#8220;Servlet.init() for servlet action threw exception”
一般出现这U异常在后面?x)显CZ个关于ActionServlet的异常堆栈信息,其中指出了异常具体出现在代码的哪一行。我曄遇到的一ơ提C如下:(x)
java.lang.NullPointerException
at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1003)
at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:955)
决问题,先下载struts的源码包Q然后在ActionServlet.java的第1003行插入断点,q对各变量进行监视。很丢hQ我竟然把struts-config.xml文g弄丢了,因此出现了上面的异常Q应该是和CVS同步时不心删除的?
11?#8220;Resources not defined for Validator”
q个是利用Validator插g做验证时可能出现的异常,q时你要(g)查validation.xml文gQ看里面使用的资源是否确实有定义Qform的名U是否正,{等?/p>