Love Pisces

It's not your aptitude but your attitude that determines your altitude!
posts - 2, comments - 43, trackbacks - 0, articles - 9

Struts应用:helloapp

Posted on 2007-06-01 11:16 筱筱 阅读(283) 评论(0)  编辑  收藏 所属分类: Struts学习日记

1.分析helloapp应用的需求 
    ·接受用户输入的姓名<userName>,然后返回字符串"Hello<userName>!"。
    ·如果用户没有输入姓名就提交表单,将返回出错信息,提示用户首先输入姓名。
    ·如果用户输入姓名为"Monster",将返回出错信息,拒绝向"Monster"打招呼。


2. 运用Struts框架 
     ·模型包括一个JavaBean组件PersonBean,它有一个userName属性,代表用户输入的名字。它提供了get/set方法,分别用于读取和设置userName属性,它还提供一个save()方法,负责把userName属性保存到持久化存储系统中,如数据库或文件系统。对于更为复杂的Web应用,JavaBean组件可以作为EJB或Web服务的前端组件。
    ·视图包括一个JSP文件hello.jsp,它提供用户界面,接受用户输入的姓名。视图还包括一个ActionForm Bean,它用来存放表单数据,并进行表单验证,如果用户没有输入姓名就提交表单,将返回出错信息。 
    ·控制器包括一个Action类HelloAction,它完成三项任务:1.进行业务逻辑验证,如果用户输入的姓名为"Monster", 将返回错误消息;2.调用模型组件PersonBean的save()方法,保存用户输入的名字;3.决定将合适的视图组件返回给用户。
     ·除了创建模型、视图和控制器组件,还需要创建Struts的配置文件struts-config.xml,它可以把这些组件组装起来,使它们协调工作。此外,还需要创建整个Web应用的配置文件web.xml。

3.创建视图组件
       本例中,视图包括两个组件:
                      ·一个JSP文件:hello.jsp
                      ·一个ActionForm Bean: HelloForm Bean (HelloForm.java)。
       其中,jsp中有代码<html:bean action="/HelloWorld" focus="userName">
      当用户提交了HTML表单后,Struts框架将自动把表单数据组装到ActionForm Bean中。ActionForm Bean中的属性和HTML表单中的字段一一对应。ActionForm Bean还提供了数据验证方法,以及把属性重新设置为默认值的方法。Struts框架中定义的ActionForm类是抽象的,必须在应用中创建它的子类,来存放具体的HTML表单数据。
       HelloForm.java中有两个特殊的方法:
    ·validate():用于表单验证。
    ·reset():把属性重新设置为默认值。
        本例中的资源文件是application.properties,用来存放数据信息。

4.创建控制器组件:HelloAction.java 
      控制器组件包括ActionServlet类和Action类。ActionServlet类是Struts框架自带的,它是整个Struts框架的控制枢纽,通常不需要扩展。Struts框架提供了可供扩展的Action类,它用来处理特定的HTTP请求。
 所有的Action类都是org.apache.struts.action.Action的子类,Action子类应该覆盖父类的execute()方法。
HelloAction.java的代码如下:

package hello;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;

import com.yourcompany.struts.PersonBean;
import com.yourcompany.struts.form.HelloForm;
/** 
 * @struts.action path="/hello" name="helloForm" input="/form/hello.jsp" scope="request" validate="true"
 */
public final class HelloAction extends Action {

 /**
  * Method execute
  * @param mapping:ActionMapping包含了这个Action的配置信息和Struts-config.xml文件中的<action>元素对应。
  * @param form:ActionForm包含了用户的表单数据,当Struts框架调用execute()方法时,ActionForm中的数据
  *已经通过了表单验证。
  * @param request:HttpServletRequest当前的HTTP请求对象
  * @param response:HttpServletResponse当前的HTTP响应对象
  * @return ActionForward
  */
 public ActionForward execute(
  ActionMapping mapping,
  ActionForm form,
  HttpServletRequest request,
  HttpServletResponse response) throws Exception{
    
  /* These "massage come from the ApplicationResources.properties file"
   * getResources(HttpServletRequest request)方法返回当前默认的MessageResource对象,它封装了Resource
   *Bundle 中的文本内容。  
   * 接下来Action类就可以通过MessageResource对象来访问文本内容。例如:如果要读取消息key   
   *为"hello.jsp.title"对应的文本内容,可以调用MessageResources类的getMessage(String key)方法:
   *String title=messages.getMessage("hello.jsp.title");
   * MessageResources messages=getResources(request);
   */
  /*
   * Validate the request parameters specified by the user
   * Note: Basic field validation done in  HelloForm.java
   * Business logic validation done in HelloAction.java
   * 如果用户输入的姓名为"Monster",将创建包含错误信息的AcrionMessage对象,ActionMessage对象被保存
   *到ActionMessages对象中。接下来调用在Action基类中定义的saveErrors()方法,它负责把ActionMessages
   *对象保存到request范围内。最后返回ActionForward对象,Struts框架会根据ActionForward对象包含的转发
   *信息把请求转发到恰当的视图组件,视图组件通过<html:errors>标签把request范围内的ActionMessages对象
   *中包含的错误消息显示出来,提示用户修改错误。  
   * */
      ActionMessages errors=new ActionMessages();
      String userName=(String)((HelloForm) form).getUserName();
  
      String badUserName="Monster";
  
      if(userName.equalsIgnoreCase(badUserName))
      {      
    //equalsIgnoreCase方法同vequals,只不过equalsIgnoreCase 是忽略大小写。
       errors.add("username",new ActionMessage("hello.dont.talk.to.monster",badUserName));
       saveErrors(request,errors);
       return (new ActionForward(mapping.getInput()));
      }
  /*
   * HelloAction类创建了一个模型组件PersonBean对象,并调用它的saveToPersistentStore()方法来保存userName
   *属性。
   * from the View,we now update the model
   *
   * */
     PersonBean pb=new PersonBean();
     pb.setUserName(userName);
     pb.saveToPersistentStore();
  /*
   * 把PersonBean对象保存在request范围内内
   * 从request范围内删除ActionForm Bean。由于后续的请求转发目标组件不再需要HelloForm Bean,所以
   *可将它删除。当HelloAction类调用HttpServletRequest的setAttribute()方法,向hello.jsp传递PersonBean对象时,
   *需要提供一个名为“persinbean”的属性key:request..setAttribute("personbean",pb);
   * hello.jsp通过这个名为"personbean"的属性来读取PersonBean对象:
   * <login:present name="personbean" scope="request">
   * <h2>Hello <bean:write name="personbean" property="userName"/>!</h2>
   * </logic:persent>
   * 对于Struts应用,提倡将这些属性key常量定义在一个Java文件Constant.java中,例如本例。
   * */
     request.setAttribute(com.yourcompany.struts.Constants.PERSON_KEY,pb);
  
     request.removeAttribute(mapping.getAttribute());
  
     return (mapping.findForward("SayHello"));
    }
}

5.创建模型组件
      本例的模型组件是PersonBean.java,PersonBean是一个非常简单的JavaBean,它包括一个userName属性,以及相关的get/set方法。此外,它还有一个业务方法saveToPersistentStore()。

6. 创建存放常量的Java文件:Constant.java

7.创建配置文件web.xml和struts-config.xml

本例的运行流程为:

1.Servlet容器在web.xml文件中寻找<url-pattern>属性为"*.do"的<servlet-mapping>元素:
   <servlet-mapping>
   <servlet-name>action</servlet-name>
   <url-pattern>*.do</url-pattern>
   </servlet-mapping>

2.Servlet容器依据以上<servlet-mapping>元素的<servlet-name>属性"action",在web.xml文件中寻找匹配的<servlet>元素:
   <servlet>
   <servlet-name>action</servlet-name>
   <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
   </servlet>

3.Servlet容器把请求转发给以上<servlet>元素指定的ActionServlet,ActionServlet依据用户请求路径"/HelloWorld",在Struts配置文件中检索path属性为"/HelloWorld"的Action元素:
   <action
       path="/HelloWorld"      
       type="hello.HelloAction"
       name="HelloForm"
       attribute="inputForm"
       scope="request"
       validate="true"
       input="/hello.jsp"
      >
      <forward name="SayHello" path="/hello.jsp" />
   </action>

4.ActionServlet根据<action>元素的name属性,创建一个HelloForm对象,把客户提交的表单数据传给HelloForm对象,再把HelloForm对象保存在<action>元素的scope属性指定的request范围内。

5.由于<action>元素的validate属性为true,ActionServlet调用HelloForm对象的validate()方法执行表单验证。

      ·当文本框中不输入姓名的时候,vallidate()方法返回一个ActionErrors对象。
          ActionServlet把HelloForm的validate()方法返回的ActionErrors对象保存在request范围内,然后根据<action>元素的input属性,把客户请求转发给hello.jsp。

      ·当文本框中输入姓名"Monster"的时候,vallidate()方法返回ActionErrors对象中不包含任何ActionMessage对象,表示表单验证成功。
         ActionServlet查找HelloAction实例是否存在,如果不存在就创建一个实例,然后调用HelloAction的execute()方法。
          HelloAction的execute()方法先进行逻辑验证,由于没有通过逻辑验证,就创建一个ActionMessage对象,这个ActionMessage对象封装了错误消息,execute()方法把ActionMessage对象保存在ActionMessages对象中,再把ActionMessages对象存放在request范围内。最后返回一个ActionForward对象,该对象包含的请求转发路径为<action>元素的input属性指定的hello.jsp。

      ·当文本框中输入其他姓名的时候,vallidate()方法返回ActionErrors对象中不包含任何ActionMessage对象,表示表单验证成功。
          HelloAction的execute()方法进行逻辑验证,这次通过了验证,然后执行相关的业务逻辑,最后调用ActionMapping.findForward()方法,参数为“SayHello”:return (mapping.findForward("SayHello"));
          ActionMapping.findForward()方法从<action>元素中寻找name属性为“SayHello”的<forward>子元素,然后返回与之对应的ActionForward对象,它代表的请求转发路径为“/hello.jsp”。
          HelloAction的execute()方法把ActionForward对象返回给ActionServlet,ActionServlet再把客户请求转发给hello.jsp。
 hello.jsp的<bean:message>标签从Resource Bundle中读取文本,把它们输出到网页上,最后生成动态网页。
                     


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


网站导航: