Sung in Blog

           一些技术文章 & 一些生活杂碎
只要你使用了Struts一段时间,你就会开始注意到你花了很多时间来创建ActionForm 类。尽管这些类对于Struts的MVC结构很重要(因为他们实现了视图部分),但他们通常只是bean属性和 validate 方法(有时也称为reset 方法)的汇集。有了Struts 1.1版本,开发者就有了一组新的选项来创建他们的视图对象,在DynaBeans的基础上创建。DynaBeans是动态配置的Java Beans,这就意味着:他们可从外部配置(通常为XML)的某些种类中获取他们的属性,而不是通过在类中明确定义的方法处获得。

为了说明DynaBeans (和Struts实现,Dynaforms)的工作原理,我们首先讨论一个简单的 Struts Form ,它主要记录姓名、地址、和电话号码。下面就是如何使用ActionForm 来实现它的过程。

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;
    }
}


如你所见,这是一个带有有效方法的标准JavaBean,它保证所有的域都正确设置。

与这个bean接口的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只发送值到标准输出(它会将值放在 Catalina 日志文件内):

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");
    }
}



原文地址:http://www.developer.com/java/ejb/article.php/2214681

这就是一起绑定的所有东西,他们总是与Struts一起,放在struts-config.xml 文件内:





<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链接到刚刚定义的CustomerForm 类上, /addCustomer动作也是定义用来使用该表格和使用article1.AddCustomerAction类来处理请求。

当你将表格放在了你的浏览器上,你需要填写下列空白表格:



如果你提交了无任何实际内容的表格,就会出现下列内容:



当你认真填写了表格并提交后,在你的Web容器日志文件内(在Tomcat 下为catalina.out )就会出现下列内容:

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


至此,这都是人人熟知的Struts。但是,通过使用Struts 1.1的某些新特征,你可以彻底的删除原本需要编写的大量代码。例如: 我们使用Dynaform扩展,就不需要ActionForm类。如果这样的话,我们需要修改struts-config.xml 中的customerForm 的定义,以便使用org.apache.struts.action.DynaActionForm类(为了这篇指南,我们实际上将创建一个新的类和JSP页,这样你就能够比较他们两个)

通过使用DynaActionForm,你获得到form-property XML标记的访问,这个标记允许你直接定义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页做任何修改;DynaForms的使用对Struts HTML标记库是透明的。你确实需要对Action稍微修改一下,但是,因为你不能够再将传递到execute()方法内的表格直接传递给拥有存取器(用于你的数据的GET和SET方法)的类中。相反,你需要将表格传递给DynaActionForm,并且需要使用普通的get(fieldname)存取器。所以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;
 }

}


请再次注意:我们需要使用get()存取器,而不是直接访问实际变量。我们也需要修改struts-config.xml 中表格的定义,以便用这个新类来取代一般的DynaActionForm 类。如果这样的话,就会重新获得校验功能。但是,我们得重新为每个表格定义明确的类。在Struts 1.1下进行校验,我推荐的方法是使用Struts Validator 框架,它将在后续文章中进行说明。

在本系列的下一篇文章中,我们将看到DynaForms 的更高级的用途。特别是,我们将教你如何使用编入索引的属性和beans排列来实现复杂的细节繁琐的表格。

posted on 2005-10-24 22:12 Sung 阅读(251) 评论(0)  编辑  收藏 所属分类: Struts

只有注册用户登录后才能发表评论。


网站导航: