创建控制器组件:HelloAction.java

来源:互联网 发布:维科网络 编辑:程序博客网 时间:2024/06/09 18:08
创建控制器组件:HelloAction.java
控制器组件包括ActionServlet类和Action类。ActionServlet类是Struts框架自带的,它是整个Struts框架的控制枢纽,通常不需要扩展。Struts框架提供了可供扩展的Action类,它用来处理特定的HTTP请求,例程2-4为HelloAction类的源程序。
例程2-4  HelloAction.java
package hello;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;

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

public final class HelloAction extends Action {

    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an ActionForward instance describing where and how
     * control should be forwarded, or null if the response has
     * already been completed.
     */
    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
    throws Exception {

        // These "messages" come from the ApplicationResources.properties file
        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
         */
        ActionMessages errors = new ActionMessages();
        String userName = (String)((HelloForm) form).getUserName();

        String badUserName = "Monster";

        if (userName.equalsIgnoreCase(badUserName)) {
           errors.add("username", new ActionMessage("hello.dont.talk.to.monster",
badUserName ));
           saveErrors(request, errors);
           return (new ActionForward(mapping.getInput()));
        }

        /*
         * Having received and validated the data submitted
         * from the View, we now update the model
         */
        PersonBean pb = new PersonBean();
        pb.setUserName(userName);
        pb.saveToPersistentStore();

        /*
         * If there was a choice of View components that depended on the model
         * (or some other) status, we'd make the decision here as to which
         * to display. In this case, there is only one View component.
         *
         * We pass data to the View components by setting them as attributes
         * in the page, request, session or servlet context. In this case, the
         * most appropriate scoping is the "request" context since the data
         * will not be neaded after the View is generated.
         *
         * Constants.PERSON_KEY provides a key accessible by both the
         * Controller component (i.e. this class) and the View component
         * (i.e. the jsp file we forward to).
         */

        request.setAttribute( Constants.PERSON_KEY, pb);

        // Remove the Form Bean - don't need to carry values forward
        request.removeAttribute(mapping.getAttribute());

        // Forward control to the specified success URI
        return (mapping.findForward("SayHello"));
    }
}

    HelloAction.java是本应用中最复杂的程序,下面分步讲解它的工作机制和流程。

    Action类的工作机制

    所有的Action类都是org.apache.struts.action.Action的子类。Action子类应该覆盖父类的execute() 方法。当ActionForm Bean被创建,并且表单验证顺利通过后, Struts框架就会调用Action类的execute()方法。execute()方法的定义如下:

public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException ;


    execute()方法包含以下参数:
    ·ActionMapping:包含了这个Action的配置信息,和struts-config.xml文件中的元素对应。
    ·ActionForm:包含了用户的表单数据,当Struts框架调用execute()方法时,ActionForm中的数据已经通过了表单验证。
    ·HttpServletRequest:当前的HTTP请求对象
    ·HttpServletResponse:当前的HTTP响应对象

    Action类的execute()方法返回ActionForward对象,它包含了请求转发路径信息。

    访问封装在MessageResources中的本地化文本

    在本例中,Action类的execute()方法首先获得MessageResources对象:
MessageResources messages = getResources(request);

    在Action类中定义了getResources(HttpServletRequest request)方法,该方法返回当前默认的MessageResources对象,它封装了Resource Bundle中的文本内容。接下来Action类就可以通过MessageResources对象来访问文本内容。例如,如果要读取消息key为"hello.jsp.title"对应的文本内容,可以调用MessageResources类的getMessage(String key)方法:
String title=messages.getMessage("hello.jsp.title");

    业务逻辑验证

    接下来,Action类的execute()方法执行业务逻辑验证:

ActionMessages errors = new ActionMessages();String userName = (String)((HelloForm) form).getUserName();String badUserName = "Monster";if (userName.equalsIgnoreCase(badUserName)) {   errors.add("username", new ActionMessage("hello.dont.talk.to.monster", badUserName ));   saveErrors(request, errors);   return (new ActionForward(mapping.getInput()));}


    如果用户输入的姓名为"Monster",将创建包含错误信息的ActionMessage对象,ActionMessage对象被保存到ActionMessages对象中。接下来调用在Action基类中定义的saveErrors()方法,它负责把ActionMessages对象保存到request范围内。最后返回ActionForward对象,Struts框架会根据ActionForward对象包含的转发信息把请求转发到恰当的视图组件,视图组件通过标签把request范围内的ActionMessages对象中包含的错误消息显示出来,提示用户修改错误。

    在本文中还提到了ActionErrors对象,图2-3显示了ActionMessages、ActionErrors、ActionMessage和ActionError类的类框图。ActionErrors继承ActionMessages,ActionError继承ActionMessage,ActionMessages和ActionMessage之间为聚集关系,即一个ActionMessages对象中可以包含多个ActionMessage对象。


图2-3 ActionMessages、ActionErrors、ActionMessage和ActionError类的类框图

    表单验证通常只对用户输入的数据进行简单的语法和格式检查,而业务逻辑验证会对数据进行更为复杂的验证,很多情况下,需要模型组件的介入,才能完成业务逻辑验证。

    访问模型组件

    接下来,HelloAction类创建了一个模型组件PersonBean对象,并调用它的saveTopersistentStore()方法来保存userName属性:

PersonBean pb = new PersonBean();pb.setUserName(userName);pb.saveToPersistentStore();


    本例仅提供了Action类访问模型组件简单的例子。在实际应用中,Action类会访问模型组件,完成更加复杂的功能,例如:
    ·从模型组件中读取数据,用于被视图组件显示
    ·和多个模型组件交互
    ·依据从模型组件中获得的信息,来决定返回哪个视图组件

    向视图组件传递数据

    Action类把数据存放在request或session范围内,以便向视图组件传递信息。以下是 HelloAction.java向视图组件传递数据的代码:

request.setAttribute( Constants.PERSON_KEY, pb);// Remove the Form Bean - don't need to carry values forwardrequest.removeAttribute(mapping.getAttribute());


    以上代码完成两件事:
    ·把PersonBean对象保存在request范围内。
    ·从request范围内删除ActionForm Bean。由于后续的请求转发目标组件不再需要HelloForm Bean,所以可将它删除。

    把HTTP请求转发给合适的视图组件

    最后,Action类把流程转发给合适的视图组件。

// Forward control to the specified success URIreturn (mapping.findForward("SayHello"));


(T111)



本文选自飞思图书《精通Struts:基于MVC的Java Web设计与开发》
原创粉丝点击