重温struts

今天公司让我维护一个老的程序,拿到手后才知道前台是用struts1。这让我回想起一年前刚学习struts的时候,那时我还还处于J2EE的懵懂期,写程序只能照葫芦画瓢,现在通过深入的学习MVC,jsp,servlet后才能发现一种struts框架的精妙之处。

struts1中最主要学习的就是actionForm和tag,别的玩过jsp+javabean+servlet的应该不难理解,其中tag由于过多,我也不深入介绍,其实tag中常用的也就几个,千万不要被tag的量给吓倒。在这我主要讲下actionForm。

 

首先,浏览器将所有的东西都按字符串提交。你可以使用JavaScript校验来强迫用户在某个域里面只能输入数字,或者使用固定的数据格式,但是这也仅是镜花水月。所有的东西仍然以字符串的方式提交给服务器—而不象准备传递给Java方法的二进制对象。
重要的是要记住,这是浏览器和HTML 工作的方式。
Web 应用无法控制这些。Struts 之类的框架的存在是使我们必须做的事情做的最好。Struts对HTTP 数据输入难题的解决方法是使用ActionForm。在象Swing 之类的环境中,数据输入控件有一个内建的文本缓冲区,可以校验所输入的字符。当用户离开控件,缓冲区可以转换为二进制类型,可以传递给业务层。不幸的是HTTP/HTML 平台不提供可以缓冲、校验和输入转换的组件。所以Struts 框架提供了一个ActionForm (org.apache.struts.action.ActionForm)类来沟通web浏览器和业务对象。ActionForm 提供了想要的缓冲/校验/转换机制,我们可以用来保证用户输入它们想要输入的东西。当 HTML 表单提交时,名-值对被Struts 控制器获取,并应用到ActionForm。ActionForm是一个 JavaBean,有属性和HTML 表单控件中的域相对应。 Struts 比较ActionForm 属性的名称和输入名-值对的名称。当匹配时,控制器设置属性值为相关的输入域的值。其它的属性会被忽略。错过的属性会保持它们的缺省值(通常是null 或者false)。

 

ActionForm是窗体的对象化表示,它本身其实是个JavaBean,除了标准的getter与setter等方法之外,还提供有reset()、validate()等方法供Struts组件呼叫。

当透过发送请求来到ActionServlet后,ActionServlet会从ActionMapping对象中得知所使用的ActionForm对象,这是在struts-config.xml中设定的,如果所需的ActionForm还不存在就生成一个,之后一直使用它,ActionMapping与ActionForm对象会被当作参数传递给Action对象。

在Struts 1.1中,ActionForm生成之后,会执行RequestProcessor的processPopulate()方法,首先它会呼叫 ActionForm的reset()方法,您可以在当中作一些重清ActionForm属性的动作,然而窗体的参数值会与ActionForm的 setter进行比对,如果有名称符合的就将窗体的参数值设定给对应的属性。

我们透过继承ActionForm类别来使用它,下面是一个简单的例子:

   

ActionForm类别编译后必须放置于WEB-INF中,并包括套件阶层,我们必须在struts-config.xlm中定义Action对象使用哪一个ActionForm对象:

 

<struts-config>
    <form-beans>
        <form-bean
            name="userForm"
            type="onlyfun.caterpillar.UserForm"/>
    </form-beans>
                                                                                
    <global-forwards>
        <forward
            name="welcome"
            path="/Welcome.do"/>
    </global-forwards>
                                                                               
    <action-mappings>
        <action
            path="/Welcome"
            type="org.apache.struts.actions.ForwardAction"
            parameter="/pages/Welcome.jsp"/>
                                                                               
         <action
            path="/LoginAction"
            type="onlyfun.caterpillar.LoginAction"
            name="userForm">
            <forward
                name="greeting"
                path="/pages/greeting.jsp"/>
        </action>
    </action-mappings>
    <message-resources parameter="resources.application"/>
</struts-config>

 


在这个例子中,<form-bean>标签定义了所使用的ActionForm对象及 名称,而在<action>标签的设定中,LoginAction指定了userForm作为其所使用的ActionForm,我们的 LoginAction类别如下:
ActionForm被作为参数传递至execute()方法,我们必须转换为其原来的形态 UserForm,这样才可以取出当中的属性值,在验证使用者的名称与密码无误后,我们查找greeting的ActionForward对象并传回,这 会使得ActionServlet将请求forward至greeting.jsp:
<html:form>指定的LoginAction必须在struts-config.xml 中有定义,<html:text>与<html:password>会取出对应的ActionForm对象中对应的属性值,如果 使用者填写的内容不正确而被送回Welcome.jsp,使用者将可以看到先前所填写的值,如果不想显示先前所填写的值,则将<html: text>与<html:password>的redisplay属性设定为false即可,这几个Struts卷标必须与Action对象及ActionForm对象搭配使用。

接下来您可以测试一下程序,连上http://localhost:8080/HelloStruts/,如果您填写了正确的窗体字段并送出,则结果会如下:
<html lang="zh">
<head>
<title>哈啰!Struts!</title>
<base href="http://localhost:8080/HelloStruts/pages/greeting.jsp">
</head>
<body bgcolor="white">
    caterpillar您好,这是您的神秘礼物!
</body>
</html>
ActionForm在Struts中是属于视图组件的一部份,它是窗体的对象化窗体,窗体的参数会自动设定给 ActionForm,无法对应的就加以忽略,您可以定义validate()方法来验证窗体设定的内容,这在下一个主题中将加以说明,在 ActionForm中您可以填入窗体值,作一些适当的值转换,进行基本的数据验证,ActionForm是窗体数据发送至应用程序前的缓冲区,在某些程 度上,它是应用程序的防火墙,您可以在ActionForm中避免不正确或不安全的数据进入应用程序。

综合一下,ActionForm担任以下的几个职责:
*窗体字段的耕耘者
*数据的缓冲区
*数据的验证
*进行属性值的转换
*应用程序防火墙
 
 

posted on 2009-07-23 21:06  木鱼哥  阅读(135)  评论(0编辑  收藏  举报

导航