【Jsp精品源码栏目提醒】:以下是网学会员为您推荐的Jsp精品源码-【大学课件】第7章 Struts2的高级应用 - 讲义教程,希望本篇文章对您学习有所帮助。
第7章Struts2的高级应用??本章将讲述一些Struts2的高级应用有一些是struts2提供的特殊功能大部分是由struts2提供的基本功能组合而来。
这些方法与设计模式的思路类型“面对同样的问题采用经典的、可靠的、易用的方法来解决”。
还有一些问题是Web开发中经常遇到的比如类型转换此类问题工作量巨大。
Struts2也提供了完美的解决方案使开发者从这些重复劳动中解放出来。
7.1 类型转换Type Conversion??在所有的基于Web的Java开发框架中Struts2拥有最优秀的类型转换能力。
通常情况下要利用这种能力只需要把HTML输入项表单元素和其他GET/POST的参数命名为合法的OGNL表达式。
7.1.1 为什么需要类型转换??在Web世界中输入输出是没有数据类型的概念的任何数据都被当作字符串或字符串数组来传递。
如果需要转化为其他类型如int进行计算就要使用Java的转换函数在本书关于EL章节中已经介绍过EL提供了某些转换功能如String对基本类型的数据的转化。
但这样是还是不够的当需要将一个字符串转换成为一个更为复杂的对象时类型转换能发挥强大的作用.例如如果提示用户使用字符串格式quot322quot输入一个坐标需要让Struts2完成String到Point和Point到String的转换Struts2正是提供这样的功能。
下面介绍如何配置和使用Struts2提供的类型转化。
7.1.2 定义类型转换器??类型转化器都需要实现ognl.TypeConverter类而Struts2提供了一个很好的工具类org.apache.struts2.util.StrutsTypeConverter。
该类可以让很方便的编写处理对象和字符串相互转换的类型转换器如代码所示。
7.1.3 内建的Built in类型转换支持??Struts2可以自动完成大多数常用的类型转换。
这也是为什么在struts2中字符串对基本类型如int的转化是自动完成的无需任何配置和代码。
已支持的与字符串之间转换类型包括??Struts2可以自动完成大多数常用的类型转换。
这也是为什么在struts2中字符串对基本类型如int的转化是自动完成的无需任何配置和代码。
已支持的与字符串之间转换类型包括??String??boolean/Boolean??char/Character??int/Integer、float/Float、long/Long、double/Double。
??dates使用当前request指定的Locale信息对应的SHORT格式。
??arrays假定每一个字符串都能够转换成对应的数组元素。
??collections如果不能确定对象类型将假定集合元素类型为String并创建一个新的ArrayList。
7.1.4 参数名称的关系??利用Struts2的类型转换最好的方式是直接装配对象理想情况下应当直接使用业务对象domain objects而不是使用基本类型或字符串类型的表单参数值作为中间值然后在Action的execute方法中把这些中间值组装成完整的对象下面是一些提示??使用组合的complexOGNL表达式。
Struts2能自动创建实际对象。
??使用JavaBeans。
Struts2只能创建遵守JavaBean规范的对象这需要对象提供一个无参构造函数并包含适当的getter和setter方法。
??记住person.name将调用getPerson.setName但如果希望Struts2创建Person对象那么必须包含一个setPerson方法。
??对于list和map对象使用索引符号如people0.name or friendspatrick.name。
通常这些HTML表单元素是在一个循环中绘制出来的因此可以在
JSP Tags中使用iterator标签的状态属性status attribute或在FreeMarker Tags中使用foo_index 来指定这一属性。
??对于多选的列表显然不能为每个单独的选项使用对应的属性符号来命名由于。
替代的方法是使用简单的名称people.name 来命名表单元素Struts2知道需要为每一个选中的选项创建一个新的Person对象并设定它的名字。
7.1.5 空值属性处理??Struts2还有一些非常有用的类型转换特性。
对空值Null属性的处理可以在发现空值引用时自动创建对象。
对Collection和Map的支持提供了针对Java集合的智能空值处理和类型转换。
类型转换错误处理提供了一种简单的方法可以把输入校验问题和输入类型转换问题区别开。
??通过把action context中的键值CREATE_NULL_OBJECTS 设置为true支持空值处理。
这样出现NullPointerException异常的OGNL表达式将被自动临时中断然后系统将通过创建所需对象的方法来自动尝试解决null引用。
7.1.6 Collection和Map支持??Struts2支持多种方法来判断集合中的对象类型。
这是通过一个ObjectTypeDeterminer完成的。
Struts2提供了缺省实现对这个接口提供了一个缺省实现的类DefaultObjectTypeDeterminer。
??ObjectTypeDeterminer检查Class-conversion.properties文件中包含的用于表示Map和Collection中包含的对象类型的相关内容。
对于Collection如List使用格式Element_xxx来指定其中的元素类型这里xxx是action或其他对象中的集合属性名称。
对于Map需要按照格式Key_xxx和Element_xxx分别指定key和value的类型。
如上例中如果有个包含point的list属性那么conversion文件中应该配置为7.1.7 类型转换错误处理??在类型转换发生错误时有时希望报告这些错误而有时不希望报告。
例如报告输入的“abc”不能转换成数字可能很重要。
另一方面报告一个空字符串“”不能装换成数字可能不重要。
除非是在一个Web环境下难以区分用户没有输入还是输入了一个空白值。
??缺省情况下所有的转换错误使用通用的i18n信息struts.default.invalid.fieldvalue可以在全局il8n资源包中替换它缺省文本是quotInvalid field value for field xxxquot这里xxx是字段名称。
7.2 校验Validation??校验表单对于防止不正确的数据进入应用程序是必不可少的。
最好是尽可能捕获用户输入数据的问题告诉用户发生了什么错误以及他们如何来修整它这个一个用户友好系统的检验尺度。
??如果用户输入的数据是不能正确格式化并且不能正确转好到此属性的格式的时候这个问题会被在“类型转化”一章中介绍的类型转换框架捕获。
7.2.1 手动校验??最直接的校验表单数据的方式就是在action里编写校验代码。
这个方法的问题是限制了复用因为校验被限制的action类里不容易在action之间或者应用程序的其他部分服用。
但是在一些情况下一些负责的商业逻辑可能必须也只能在action类中实现也就是说手动校验可能是最后的选择。
??在第5章“acton的基本校验”一节已经介绍了如何利用Validateable接口来实现校验代码与excute函数分离以及利用ValidationAware来处理错误信息。
如果必须使用手动校验应该采用这种方法而不要把校验代码直接加入到excute方法中去。
而本节重点是如何利用struts2的框架来进行校验。
7.2.2 使用框架校验??校验框架自动读取volidation文件里面的定义进行校验。
这些文件和action类放在相同的包里命名为ClassName-voidation.xml。
这是一个SimpleAction-validation.xml的例子??校验器和字段校验器必须有一个type属性这里指向是已经注册的校验器的名字。
validators元素还必须有ltparamgt元素带有name和value属性来设置校验器实例的任何需要设置的参数。
??1校验错误信息??2用别名区分特定的校验规则??3继承关系??4打开校验7.2.3 注册校验器??校验规则是通过校验器来处理的它们必须注册到ValidatorFactory使用registerValidator 方法最简单的方法就是添加一个文件名为validators.xml的文件位置在classpath/WEB-INF/classes的根目录下来声明所有的校验器。
7.2.4 字段校验和非字段校验??非字段校验又称为简单校验器例如ExpressionValidator执行校验检查不是绑定到单一的指定的字段上的当-validation.xml 文件中声明一个简单的校验器时不需要把一个fieldname属性和它关联。
??字段校验器例如Email Validator设置用来在一个单一字段上进行校验检查。
它们要求在-validation.xml文件中执行一个fieldname属性。
有两种不同的XML语法但是等效可以用来声明字段校验器。
7.2.5 校验器的短路??使用short-circuit属性可以将校验器设置为短路也就是如果此校验无法通过立刻结束校验过程不再执行以下的其他校验器如代码所示。
??代码字段校验-validators.xml??lt--校验器的短路--gt??ltfield namequotemailquotgt??ltfield-validator typequotrequiredquot short-circuitquottruequotgt??ltmessagegtYou must enter a value for email.lt/messagegt??lt/field-validatorgt??ltfield-validator typequotemailquot short-circuitquottruequotgt??ltmessagegtNot a valid e-mail.lt/messagegt??lt/field-validatorgt??lt/fieldgt7.2.6 客户端校验??Struts2提供了客户端校验的支持。
Struts2会生成校验的JavaScript发送到浏览器端。
用户提交的时候无需再传输数据到服务器端直接在网页中检验结果这种做法可以提高响应速度。
如图所示展示了服务器端校验和客户端校验流程的区别。
7.2.7 AJAX校验实例??本节将以一个例子说明如何实现AJAX校验首先看看基本的表单校验是如何做的。
??如果实现AJAX校验有以下几个步骤??1首先要把form主题设为AJAX。
??2还需要给应用程序配置好DWRDWR通过位于/WEB-INF/目录下的dwr配置dwr.xm来设置。
??3需要注册一个DWRServlet到web应用程序中。
下面显示了一个典型的配置了DWR Serlvet的web.xml7.3 国际化??开发国际化的Web应用是很艰苦的本书不期望能涵盖这个挑战性的话题的所有方面。
Struts2提供了广泛的功能可以处理构建一个国际化应用程序的技术方面。
Struts的国际化功能也可以用其他领域如格式化日期等数据。
7.3.1 信息的来源??为了给不同的地区提供不同的字符串信息需要一个应用程序的源文件来为给定的locale找到正确的字符串信息。
幸运的是Java以Java.util.ResourceBundle抽象类的方式提供了这些功能。
JDK带来了资源包的实现java.util.PropertyResouceBundle和java.util.ListResouceBundle。
这两个类会自动加载含有这些国际化信息的属性文件.properties文件。
当ResourceBundle.getBundle被调用的时候会查找正确的ResourceBundle名字如CreateLocalizedCategory.properties缺省一般是英文、CreateLocalizedCategory_zh.properties简体中文或者CreateLocalizedCategory_de.properties德文。
7.3.2 资源包搜索顺序??资源包按照下面的顺序搜索??1ActionClass.properties。
??2BaseClass.properties。
??3Interface.properties 每一个接口和子接口。
??4ModelDriven的model如果实现了ModelDriven对于model对象从第一步重复执行。
??5package.properties 类所在的目录和每个父目录直到根目录。
??6搜索i18n message key 自己的层次关系。
??7全局资源属性struts.custom.i18n.resources在struts.properties里定义的。
7.3.3 添加默认的资源包??经常会有一系列的信息用于应用程序中并且经常要在得到一个本地化的信息是让那个应用程序可以得到它们。
Struts提供了几种方法来配置这些本地化信息的??1通过配置属性或者编程的方式注册默认资源包的功能。
修改struts.properties文件中的struts.custom.i18n.resources属性如??struts.custom.i18n.resourcesorg.hibernate.auction.i18n??2资源包可以被添加到一个启动类中例如ServletContextListerner方法是通过对com.LocaclizedTextUtil类做调用??LocaclizedTextUtil.addDefaultResouceBundle“org.hibernate.auction.i18n”??3lts:i18ngt标签??除了确定的默认资源包搜索之外可以通过lts:i18ngt标签来是一个资源包在
JSP页面里可用。
7.3.4 使用国际化信息??本节将介绍如何利用Struts2的几种技术配合使用来实现国际化。
??1使用lts:textgt标签??2在标签属性中使用getText??3格式化日期和数字??4在校验里使用国际化信息??5类型转换中使用国际化信息7.4 处理上传文件??Struts2是通过Commons FileUpload文件上传。
Commons FileUpload通过将HTTP的数据保存到临时文件夹然后Struts使用fileUpload拦截器将文件绑定到Action的实例中。
就能够以本地文件方式的操作浏览器上传的文件。
本节将以一个例子来介绍如何在Struts2中实现文件上传。
??说明Commons FileUpload也是开源组件Apache Commons的一部分专门解决Java在http中上传文件的问题详细信息请参考它的
源码网站“http://commons.apache.org/fileupload/”7.4.1 编写文件上传页面??首先创建文件上传页面FileUpload.
Jsp内容如代码7-17所示。
在FileUpload.
Jsp中先将表单的提交方式设为POST然后将enctype设为multipart/form-data这并没有什么特别之处。
接下来lts:file/gt标志将文件上传控件绑定到Action的myFile属性。
文件的界面如图7.5所示。
7.4.2 构造处理上传的Action??如代码所示在FileUploadAction中分别包含setMyFileContentType、setMyFileFileName、setMyFile和setCaption四个Setter方法后两者很容易明白分别对应FileUpload.
jsp中的lts:file/gt和lts:textfield/gt标志。
但是前两者并没有显式地与任何的页面标志绑定那么它们的值又是从何而来的呢其实lts:file/gt标志不仅仅是绑定到myFile还有myFileContentType上传文件的MIME类型和myFileFileName上传文件的文件名该文件名不包括文件的路径。
因此lts:file namequotxxxquot /gt对应Action类里面的xxx、xxxContentType和xxxFileName三个属性。
7.4.3 编写结果页面??下面就来看看上传成功的页面ShowUpload.
jsp获得imageFileName将其UploadImages组成URL从而将上传的图像显示出来如代码所示。
??代码上传文件结果ShowUpload.
jsp??lt page languagequotjavaquot importquotjava.util.quot pageEncodingquotUTF-8quotgt??lt taglib prefixquotsquot uriquot/struts-tagsquot gt??lthtmlgt??ltheadgt ??lttitlegt Struts2 File Upload lt/titlegt ??lt/headgt ??ltbody gt ??ltdiv style quotpadding: 3px border: solid 1px cccccc text-align: centerquotgt ??ltimg src UploadImages/lts:property value quotimageFileNamequot /gt/gt??ltbr/gt ??lts:property value quotcaptionquot/gt ??lt/divgt ??lt/bodygt ??lt/htmlgt7.4.4 更多配置??在运行上述例子会发现服务器控制台有如下输出??Mar 20 2007 4 : 08 : 43 PM org.apache.struts2.dispatcher.Dispatcher getSaveDir??INFO: Unable to find struts.multipart.saveDir property setting. Defaulting to javax.servlet.context.tempdir??Mar 20 2007 4 : 08 : 43 PM org.apache.struts2.interceptor.FileUploadInterceptor intercept??INFO: Removing file myFile C:Program FilesTomcat 5.5 work Catalina localhost Struts2_Fileupload upload_251447c2_1116e355841 __ 7ff7_00000006.tmp7.4.5 错误处理??上述例子实现的图片上传的功能实际中可能需要阻止用户上传非图片类型的文件。
在Struts2中如何实现这点呢其实这也很简单对上述例子作如下修改即可。
??上传文件页面FileUpload.
jsp??lt page language quotjavaquot contentType quottext/html charsetutf-8quotgt ??lt taglib prefixquotsquot uriquot/struts-tagsquot gt??lthtmlgt??ltheadgt ??lttitlegt Struts2 File Upload lt/titlegt ??lt/headgt ??ltbodygt ??lts:form action quotfileUploadquot method quotPOSTquot enctype quotmultipart/form-dataquot gt ??lts:file name quotmyFilequot label quotImage Filequot /gt ??lts:textfield name quotcaptionquot label quotCaptionquot /gt ??lts:submit /gt ??lt/s:form gt??lts:fielderror/gt ??lt/bodygt ??lt/htmlgt??7.4.6 多文件上传??与单文件上传相似Struts2实现多文件上传也很简单。
可以将多个lts:file/gt绑定Action的数组或列表。
??代码多文件上传FileUpload.
jsp??lt s:form action quotdoMultipleUploadUsingListquot method quotPOSTquot enctype quotmultipart/form-dataquot gt ??lt s:file label quotFile 1quot name quotuploadquot /gt ??lt s:file label quotFile 2quot name quotuploadquot /gt ??lt s:file label quotFIle 3quot name quotuploadquot /gt ??lt s:submit /gt ??lt/ s:form gt7.5 防止重复提交??作为一个Web应用的开发程序员Web应用的无限制特性会给应用带来很多问题。
这里的问题是客户端控制着访问Web应用的请求可能得到非预期的不同顺序的Web应用请求或者多次得到相同的多请求。
当用户不止一次单击Web表单的提交按钮时候就会发生这个问题。
因为在每次单击的时候浏览器都会发送表单请求信息或者表单提交成功并显示新页面以后单击重新加载按钮也会发生问题。
这种情况相当危险因为表单提交时要求服务器完成某种操作信号并且许多action不应该执行多次。
7.5.1 使用lts:tokengt标签增加标记??lts:tokengt标签创建一个新的表单标记并用token做关键值把token的值保存到session中。
这个token的值是一个经过加密的、非常安全的UUID所以不用担心出现重复的token值或者用户推测出token值的情况。
代码7-26演示了一个使用token标签的例子。
7.5.2 使用tokeninterceptor验证??在配置文件中为action定义com.opensymphony.webwork.interceptor.TokenInterceptor就可以根据Web请求参数来验证标记了。
想要保证interceptor正常工作首先应该确保以下条件7.5.3 使用TokenSessionStoreInterceptor重新输出结果页面??com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor扩展了Token-Interceptor重写了handleInvalidToken方法和handleValidToken方法。
在TokenSession -StoreInterceptor中handleValidToken在session中保存了一个包含actionInvocation和标记值的对象。
如果有重复提交并且重用了同样的标记这个对象会被从session中取出并根据保存的action的状态重新输出结果页面这里的action不需要再被执行一次。
这样可以效地防止重复提交引发的action重复执行这可以给用户带来更好的用户体验他们重新看到一个相同的结果页面这比得到一个错误页面要好很多。
7.6 自动等待页面??等待页面是一个很常见的用例比较耗时的操作都需要提提供一个等待页面给用户。
Struts2提供了execAndWati interceptor可以为用户返回一个等待页面时在另外一个线程中运行action。
??首先需要使用struts实现一个正常的处理流程。
如图所示显示了用户请求的流程必须在ation的所有工作完成之后才能包页面返回给用户。
无论如何action执行的时间有多长用户等待反馈页面的时间就有多长。
7.7 控制反转IoC??Ioc是Inversion of Control的缩写即反转模式。
这里有著名的好莱坞理论“你呆着别动到时我会找你”。
Ioc又名为Dependency Injection中文是依赖注射也就是将类之间的关系通过第三方进行注射不需要类自己去解决调用关系。
关于Ioc的详细解释和优点将在本书的Spring篇重点解释本节仅介绍如何在Struts2中采用Ioc??众所周知Struts2是以Webwork作为基础发展出来。
而在Webwork 2.2之前的Webwork版本其自身有一套控制反转的实现Webwork 2.2在Spring 框架的如火如荼发展的背景下决定放弃控制反转功能的开发转由Spring实现。
值得一提的是因为有越来越多的开源组件如iBATIS等都放弃与Spring重叠的功能的开发。
因此Struts2推荐通过Spring实现控制反转。
7.7.1 配置Spring??Struts2对明确的实现了对Spring的支持的所以在Struts2中配置Spring是非常容易的。
??1将所需的Spring的jar文件加入到工程的classpath和应用程序的WEB-INF/lib下这些jar文件包括spring-web-2x.jar、spring-beans-2.x.jar、spring-core-2.x.jar、spring-context-2.0.5.jar、struts2-spring-plugin-2.x.jar这些文件都可以在struts2的发布包中找到。
2在Web应用中加入Spring的ContextLoaderListener监听器方便Spring与Web容器交互。
3struts.properties文件告知Struts2运行时使用Spring来创建对象如Action等内容如下这也是缺省配置struts.objectFactory spring 7.7.2 实现接口??遵循Spring的面向接口原则编程创建接口ChatService和默认的默认实现ChatServiceImpl类??代码Ioc接口实现ChatService.java??package tutorial??import java.util.Set??/?? Ioc接口实现??/??public interface ChatService ??Set lt String gt getUserNames??7.7.3 创建Action??接下来就该新建Action了如代码所示。
ChatAction类使用属性Getter/Setter注入法取得ChatService对象。
??代码反转控制配置struts.xml??lt package name quotStruts2_IoCquot extends quotstruts-defaultquot gt ??lt action name quotChatquot class quotchatActionquot gt ??lt resu.
上一篇:
VSM系统
下一篇:
bc80e7a0-d1f2-4595-b21d-01a76798e87a