CSDN博客

img Jplateau

Struts的动态表单的应用

发表于2003/7/23 15:40:00  1081人阅读

Struts的动态表单的应用

原文连接:http://www.developer.com/java/web/article.php/2214681

By James M. Turner

 

这篇文章以实例代码来阐述Dynaformsstruts1.1种的引用——译者注

 

如果你使用过struts先前的版本,你就会注意到你需要花费大量的时候来写ActionForm类文件,而这些类文件对于struts都是非常关键的(它充当“View”的一部分),通常它的结构就是bean properties在加上一个validate方法(有时还有reset方法)。

随着struts1.1版本的推出,开发员有了另外一种方法来完成前面的任务:使用DynaBeansDynaBeans动态生成Java Beans。这就意味着我们可以通过配置(通常利用xml

来生成formbean而不是在formbean中硬编码。

为了了解DynaBeansstruts中为Dynaforms)是如何工做的,让我们看一个简单的表单,字段有:nameaddresstelephone等,下面的代码为通常的写法(没有使用Dynaforms)。

 

article1.CustomerForm

 

package article1;
 
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionError;
import javax.servlet.http.HttpServletRequest;
 
public class CustomerForm extends ActionForm {
 
    protected boolean nullOrBlank (String str) {
        return ((str == null) || (str.length() == 0));
    }
    public  ActionErrors validate(ActionMapping mapping,
            HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        if (nullOrBlank(lastName)) {
            errors.add("lastName",
                   new ActionError("article1.lastName.missing"));
        }
        if (nullOrBlank(firstName)) {
            errors.add("firstName",
                   new ActionError("article1.firstName.missing"));
        }
        if (nullOrBlank(street)) {
            errors.add("street",
                   new ActionError("article1.street.missing"));
        }
        if (nullOrBlank(city)) {
            errors.add("city",
                   new ActionError("article1.city.missing"));
        }
        if (nullOrBlank(state)) {
            errors.add("state",
                   new ActionError("article1.state.missing"));
        }
        if (nullOrBlank(postalCode)) {
            errors.add("postalCode",
                   new ActionError("article1.postalCode.missing"));
        }
        if (nullOrBlank(phone)) {
            errors.add("phone",
                   new ActionError("article1.phone.missing"));
        }
        return errors;
    }
 
    private String lastName;
    private String firstName;
    private String street;
    private String city;
    private String state;
    private String postalCode;
    private String phone;
 
    public String getLastName() {
        return lastName;
    }
 
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
 
    public String getFirstName() {
        return firstName;
    }
 
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
 
    public String getStreet() {
        return street;
    }
 
    public void setStreet(String street) {
        this.street = street;
    }
 
    public String getCity() {
        return city;
    }
 
    public void setCity(String city) {
        this.city = city;
    }
 
    public String getState() {
        return state;
    }
 
    public void setState(String state) {
        this.state = state;
    }
 
    public String getPostalCode() {
        return postalCode;
    }
 
    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }
 
    public String getPhone() {
        return phone;
    }
 
    public void setPhone(String phone) {
        this.phone = phone;
    }
}

 

看到上边的写法(这么长一段代码[虽然大多的工具都可以自动生成setget方法]感想如何?如果要为每一个表单配备一个formbean,那么将是一件多了令人痛苦的事情——译者注),你知道了它是一个标准的JavaBean,只是多了一个validate方法,validate方法确保client断的输入都是合法的。

 

相应的jsp页面同样也是很简单的,如下:

 

customer.jsp

 

<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<%@ taglib prefix="fmt" uri="/WEB-INF/fmt.tld" %>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
 
<head>
<title>Example of a standard Customer form</title>
</head>
<h1>Example of a standard Customer form</h1>
<html:form action="/addCustomer">
Last Name: <html:text property="lastName"/>
<html:errors property="lastName" /><br>
First Name: <html:text property="firstName"/>
<html:errors property="firstName" /><br>
Street Addr: <html:text property="street"/>
<html:errors property="street" /><br>
City: <html:text property="city"/>
<html:errors property="city" /><br>
State: <html:text property="state" maxlength="2" size="2" />
<html:errors property="state" /><br>
Postal Code: <html:text property="postalCode" maxlength="5"
                                              size="5" />
<html:errors property="postalCode" /><br>
Telephone: <html:text property="phone" maxlength="11" size="11" />
<html:errors property="phone" /><br>
<html:submit/>
</html:form>

 

相应的action也没有复杂的业务代码,只是将从client端传过来的值打印到控制台。

article1.AddCustomerAction

package article1;
 
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionForm;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
 
public class AddCustomerAction extends Action {
    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
    throws ServletException, IOException{
        CustomerForm custForm = (CustomerForm) form;
        System.out.println("lastName   = "
                            + custForm.getLastName());
        System.out.println("firstName  = "
                            + custForm.getFirstName());
        System.out.println("street     = " + custForm.getStreet());
        System.out.println("city       = " + custForm.getCity());
        System.out.println("state      = " + custForm.getState());
        System.out.println("postalCode = "
                            + custForm.getPostalCode());
        System.out.println("phone      = " + custForm.getPhone());
 
        return mapping.findForward("success");
    }
}

 

 

下面看看struts-config.xml的配置,struts利用该配置文件将上述文件联系到一起来协同完成任务。

 

<struts-config>
<form-beans>
<form-bean name="customerForm" type="jdj.article1.Customer" />
      </form-beans>
<action-mappings>
<action path="/addCustomer" type="article1.AddCustomerAction"
                            name="customerForm" scope="request"
                            input="/addCustomer.jsp">
<forward name="success" path="/addCustomerSucceeded.jsp"
                        redirect="false" />
</action>
</action-mappings>
<message-resources parameter="ApplicationResources" />
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property value="/WEB-INF/validator-rules.xml"
              property="pathnames" />
struts-config.xml</plug-in></struts-config>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC 
  "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
  "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
 <form-beans>
  <form-bean name="customerForm" type="article1.CustomerForm" />
 </form-beans>
 <action-mappings>
  <action path="/addCustomer" type="article1.AddCustomerAction"
          name="customerForm" scope="request" input="/customer.jsp">
      <forward name="success" path="/addCustomerSucceeded.jsp"
               redirect="false" />
  </action>
 </action-mappings>
 <message-resources parameter="ApplicationResources" />
 <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
   <set-property value="/WEB-INF/validator-rules.xml"
        property="pathnames" />
 </plug-in>
</struts-config>

 

上边通过配置,customerForm来引用CustemerForm类, /addCustomeraction使用customerForm并且触发article1.AddCustomerAction来处理请求。

 

下图添加customer空表单图片

 

如果什么也没有填就提交了,将会出现下图的反馈信息:

 

如果你所有输入的信息都合法,那么在控制台你可以看到如下类似的信息:

 

lastName = Bush
firstName = George
street = 1600 Pennsylvania Avenue NW
city = Washington
state = DC
postalCode = 20500
phone = 2024561414

 

 

到现在为止,上边代码熟悉struts得都应该很熟悉但是,如果应用struts1.1的新特性,你将会用更少的代码来完成上述同样的功能。使用Dynaforms,我们应该更改customerFormstruts-config.xml中信息来使用org.apache.struts.action.DynaActionForm (为了便于读者比较使用前后的差别,我们将使用新的类新的jsp页面来完成同样的功能)

 

使用DynaActionForm,你可以利用form-property xml标签,它允许你在struts-config.xml中定义formbean的属性元素。以我们的例子来说,struts-config.xml中将是如下这个样子:

 

<form-bean name="dynaCustomerForm"
           type="org.apache.struts.action.DynaActionForm">
  <form-property name="lastName" type="java.lang.String"/>
  <form-property name="firstName" type="java.lang.String"/>
  <form-property type="java.lang.String" name="street"/>
  <form-property name="city" type="java.lang.String"/>
  <form-property name="state" type="java.lang.String"/>
  <form-property name="postalCode" type="java.lang.String"/>
</form-bean>
 

     上边的改动对于jsp页面没有任何的影响。不过你要对于原来的action进行稍微的改动应为:你现在已经不在向execute()中传递formbean(没有get set方法),所以 你应该把form转型到DynaActionForm,然后利用方法get(filename)来取得client端数据新的action代码如下

 

article1.AddDynaCustomerAction

package article1;
 
import org.apache.struts.action.*;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
 
public class AddDynaCustomerAction extends Action {
  public ActionForward execute(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response)
                       throws ServletException, IOException{
  DynaActionForm custForm = (DynaActionForm) form;
  System.out.println("lastName   = " + custForm.get("lastName"));
  System.out.println("firstName  = " + custForm.get("firstName"));
  System.out.println("street     = " + custForm.get("street"));
  System.out.println("city       = " + custForm.get("city"));
  System.out.println("state      = " + custForm.get("state"));
  System.out.println("postalCode = "
                      + custForm.get("postalCode"));
  System.out.println("phone      = " + custForm.get("phone"));
 
      return mapping.findForward("success");
     }
}

 

从上边的代码可以看出,似乎”屏蔽“了actionform,然而我们也“丢失”了一些其他的,譬如:严整输入合法性的问题。有两种方法可以恢复校验功能:一是创建一个DynaActionForm的子类,然后在子类中实现validate()方法。如下代码:

 

article1.DynaCustomerForm

package article1;
 
import org.apache.struts.action.*;
 
import javax.servlet.http.HttpServletRequest;
 
public class DynaCustomerForm extends DynaActionForm {
 
protected boolean nullOrBlank (String str) {
  return ((str == null) || (str.length() == 0));
 }
 
public ActionErrors validate(ActionMapping mapping,
                    HttpServletRequest request) {
  ActionErrors errors = new ActionErrors();
  if (nullOrBlank((String)this.get("lastName"))) {
    errors.add("lastName",
           new ActionError("article1.lastName.missing"));
  }
  if (nullOrBlank((String)this.get("firstName"))) {
    errors.add("firstName",
           new ActionError("article1.firstName.missing"));
  }
  if (nullOrBlank((String)this.get("street"))) {
    errors.add("street",
           new ActionError("article1.street.missing"));
  }
  if (nullOrBlank((String)this.get("city"))) {
    errors.add("city", new ActionError("article1.city.missing"));
  }
  if (nullOrBlank((String)this.get("state"))) {
    errors.add("state",
           new ActionError("article1.state.missing"));
  }
  if (nullOrBlank((String)this.get("postalCode"))) {
    errors.add("postalCode",
           new ActionError("article1.postalCode.missing"));
  }
  if (nullOrBlank((String)this.get("phone"))) {
    errors.add("phone", new ActionError("article1.phone.missing"));
  }
  return errors;
 }
 
}

如果是这样,我们就要更改struts-config.xml来使用DynaActionForm的子类,这样的效果似乎是又回到了先前的样子(为每一个表单写DynaActionForm),呵呵。。。

所以推荐的做法是使用struts1.1种的Validator Framework,这方面的内容在以后的文章中在说明。

 

关于作者:

 

James Turner is the owner and manager of Black Bear Software, LLC, which specializes in custom Java-based e-Commerce and CRM solutions delivery. He is also the author of "MySQL and JSP Web Applications: Data-Driven Programming Using Tomcat and MySQL" (ISBN: 0672323095) and is the co-author of "Struts: Kick Start" (ISBN: 0672324725), which will be published in November. He can be reached at turner@blackbear.com.

 

0 0

相关博文

我的热门文章

img
取 消
img