Struts框架——(三)动态ActionForm

一、DynaActionForm的引入意义

使用ActionForm把表单数据单独封装起来,而且提供了自动的数据验证,简化了代码的编写,给我们带来了极大的方便。

但是,ActionForm也存在一些明显的不足

1、如果ActionForm对应的HTML表单添加或删除一些属性,ActionForm类就可能需要修改并重新编译;所以如果HTML表单是动态的,那么ActionForm就无能为力了;

2、ActionForm增加了项目中类的数量!

3、对于安全性要求不高的系统,ActionForm的数据验证并不常用,我们一般都在js中验证了

面对这些缺点,Struts引入了动态actionform概念,动态ActionForm使得用户无须为应用程序的每一个HTML表单创建具体的ActionForm类。Struts框架包中的DyanActionForm类及其子类实现了动态ActionForm.

二、ActionForm VS DynaActionForm

 我们先来看看原来的ActionForm:

 1 package com.jialin;
 2 
 3 import org.apache.struts.action.ActionForm;
 4 
 5 /**
 6  * 用户ActionForm ,负责收集表单数据
 7  * @author jialin
 8  *注:get和set后的字符串首字母变小写后,必须和表单中属性的名字一致
 9  */
10 public class UserActionForm extends ActionForm {
11     private String name;
12     private int password;
13     public String getName() {
14         return name;
15     }
16     public void setName(String name) {
17         this.name = name;
18     }
19     public int getPassword() {
20         return password;
21     }
22     public void setPassword(int password) {
23         this.password = password;
24     }
25     
26 }

以及struts-config.xml:

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
 2 
 3 <!DOCTYPE struts-config PUBLIC
 4           "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
 5           "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
 6 
 7 <struts-config>
 8      <!-- set ActionForm info-->
 9     <form-beans>
10         <form-bean name="userForm" type="com.jialin.UserActionForm" />
11     </form-beans>
12         
13     <action-mappings>
14       <!-- Set path,action,actionform,scope,forward info -->
15         <action path="/login" type="com.jialin.LoginAction" name="userForm"
16             scope="request">
17             <forward name="success" path="/LoginSuccess.jsp" />
18             <forward name="fail" path="/LoginFail.jsp" />
19         </action>
20     </action-mappings>
21 
22 </struts-config>

DyanActionForm类扩展了 ActionForm类。动态ActionForm支持在Struts配置文件中完成ActionForm的全部配置,无须编写任何额外的Java代码。使用动态 form, 没有对应的类,所以,如果需要扩展属性,只需要再次配置文件中添加一个属性就可以了。

也就是说,最大的两个不同:1.在这里没有了ActionForm,直接在struts-config.xml中配置。2. 对属性的访问方式不同

1)没有ActionForm,配置:struts-config.xml

1. JSP:

 1 <%@ page language="java" contentType="text/html; charset=GB18030"
 2     pageEncoding="GB18030"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5     <head>
 6         <meta http-equiv="Content-Type" content="text/html; charset=GB18030">
 7         <title>Insert title here</title>
 8     </head>
 9     <body>
10         <h1>
11             测试动态ActionForm
12         </h1>
13         <form action="TestAction.do" method="post">
14             username:
15             <input type="text" name="name" />
16             <br />
17             age:
18             <input type="text" name="age" />
19             <br />
20             <input type="submit" value="提交" />
21         </form>
22     </body>
23 </html>

2. struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean name="dynamicForm" type="org.apache.struts.action.DynaActionForm">
            <form-property name="name" type="java.lang.String" />
            <form-property name="age" type="java.lang.Integer" />
        </form-bean>
    </form-beans>
    <action-mappings>
        <action path="/TestAction" type="com.jialin.TestAction" name="dynamicForm"
            scope="request">
            <forward name="showResult" path="/ShowResult.jsp" />
        </action>
    </action-mappings>
</struts-config>

2)对属性的调用方式:

同普通的ActionForm一样,Action类和JSP都可以访问动态ActionForm,而访问方式也基本一致。访问动态ActionForm与访问普通的ActionForm的最大区别在于对属性的访问方式不同

  • 我们传递的是 DynaActionForm, 所以,在调用的时候,我们就要把 form 强制转换成 DynaActionForm 对象
  • 在标准的ActionForm中,针对每一个属性都提供了getter和setter方法来读取和设置属性,而DynaActionForm把所有的属性保存在一个Map 对象中,因此访问DyanActionForm中的属性与访问Map对象中的方法类似。
 1 package com.jialin;
 2 
 3 
 4 import javax.servlet.http.HttpServletRequest;
 5 import javax.servlet.http.HttpServletResponse;
 6 
 7 import org.apache.struts.action.Action;
 8 import org.apache.struts.action.ActionForm;
 9 import org.apache.struts.action.ActionForward;
10 import org.apache.struts.action.ActionMapping;
11 import org.apache.struts.action.DynaActionForm;
12 
13 public class TestAction extends Action {
14 
15     @Override
16     public ActionForward execute(ActionMapping mapping, ActionForm form,
17             HttpServletRequest request, HttpServletResponse response)
18             throws Exception {
19      // 1. 将form转化成DynaActionForm对象
20     DynaActionForm daf=(DynaActionForm)form;
21 
22     // 2. 获取属性的方式变化——DynaActionForm把所有属性保存在一个Map中
23     String name=daf.getString("name");
24     Integer age = (Integer)daf.get("age");
25 
26     System.out.println("name=" + name);
27     System.out.println("age=" + age);
28         
29     return mapping.findForward("showResult");
30     }
31     
32 }

三、DynaActionForm的表单验证问题

DynaActionForm类的validate()方法没有提供任何默认的验证行为。可以通过定义扩展DynaActionForm类的子类,然后覆盖validate()方法,但是以编程方式来验证动态ActionForm并不是一种理想的办法。动态ActionForm的验证应该使用Struts的Validator验证插件。Validator插件允许采用特定的配置文件为动态的ActionForm配置验证规则,如检查必须的输入域,日期时间等。但这些验证我们一般都在客户端js中完成

四、DynaActionForm缺点

1、配置文件会增加,非常容易写错,而且错误不易发现。今天测试的时候,我就是把java.lang.String 写成了java.long.String 在Action中拿到的form就是null,找了老半天才解决。所以采用动态action调试比较麻烦。

2、静态ActionForm能让我们很清晰的了解表单数据信息,数据和对数据的操作是分离的,更容易让人理解。

原文地址:https://www.cnblogs.com/lesleysbw/p/6251698.html