今天公司让我维护一个老的程序,拿到手后才知道前台是用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对象:
在这个例子中,<form-bean>标签定义了所使用的ActionForm对象及 名称,而在<action>标签的设定中,LoginAction指定了userForm作为其所使用的ActionForm,我们的 LoginAction类别如下:
接下来您可以测试一下程序,连上http://localhost:8080/HelloStruts/,如果您填写了正确的窗体字段并送出,则结果会如下:
综合一下,ActionForm担任以下的几个职责:
*窗体字段的耕耘者
*数据的缓冲区
*数据的验证
*进行属性值的转换
*应用程序防火墙